mirror of
https://github.com/reactos/reactos
synced 2025-10-08 17:32:43 +02:00
Compare commits
1 Commits
backups/ca
...
ReactOS-0.
Author | SHA1 | Date | |
---|---|---|---|
|
6caaf63c2c |
@@ -1,2 +0,0 @@
|
||||
To build this branch apply the patch to trunk. And replace ntoskrnl/mm, ntoskrnl/cc with the folders from here.
|
||||
This branch currently applies against: 0.3.1 branch - r25940
|
120
cc/cacheman.c
120
cc/cacheman.c
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/cacheman.c
|
||||
* PURPOSE: Cache manager
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
PFSN_PREFETCHER_GLOBALS CcPfGlobals;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CcPfInitializePrefetcher(VOID)
|
||||
{
|
||||
/* Notify debugger */
|
||||
DbgPrintEx(DPFLTR_PREFETCHER_ID,
|
||||
DPFLTR_TRACE_LEVEL,
|
||||
"CCPF: InitializePrefetecher()\n");
|
||||
|
||||
/* Setup the Prefetcher Data */
|
||||
InitializeListHead(&CcPfGlobals.ActiveTraces);
|
||||
InitializeListHead(&CcPfGlobals.CompletedTraces);
|
||||
ExInitializeFastMutex(&CcPfGlobals.CompletedTracesLock);
|
||||
|
||||
/* FIXME: Setup the rest of the prefetecher */
|
||||
}
|
||||
|
||||
BOOLEAN NTAPI
|
||||
CcInitializeCacheManager (VOID)
|
||||
{
|
||||
CcInitView ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
LARGE_INTEGER NTAPI
|
||||
CcGetFlushedValidData (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||
IN BOOLEAN BcbListHeld)
|
||||
{
|
||||
LARGE_INTEGER i;
|
||||
|
||||
UNIMPLEMENTED;
|
||||
|
||||
i.QuadPart = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
PVOID NTAPI
|
||||
CcRemapBcb (IN PVOID Bcb)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcScheduleReadAhead (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetAdditionalCacheAttributes (IN PFILE_OBJECT FileObject,
|
||||
IN BOOLEAN DisableReadAhead,
|
||||
IN BOOLEAN DisableWriteBehind)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetBcbOwnerPointer (IN PVOID Bcb,
|
||||
IN PVOID Owner)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetDirtyPageThreshold (IN PFILE_OBJECT FileObject,
|
||||
IN ULONG DirtyPageThreshold)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetReadAheadGranularity (IN PFILE_OBJECT FileObject,
|
||||
IN ULONG Granularity)
|
||||
{
|
||||
DPRINT("CcSetReadAheadGranularity(0x%p 0x%x)\n", FileObject, Granularity);
|
||||
}
|
616
cc/copy.c
616
cc/copy.c
@@ -1,616 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/copy.c
|
||||
* PURPOSE: Implements cache managers copy interface
|
||||
*
|
||||
* PROGRAMMERS:
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
static PFN_TYPE CcZeroPage = 0;
|
||||
|
||||
#define MAX_ZERO_LENGTH (256 * 1024)
|
||||
#define MAX_RW_LENGTH (256 * 1024)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* void * alloca(size_t size); */
|
||||
#elif defined(_MSC_VER)
|
||||
void *_alloca (size_t size);
|
||||
#else
|
||||
#error Unknown compiler for alloca intrinsic stack allocation "function"
|
||||
#endif
|
||||
|
||||
ULONG CcFastMdlReadWait;
|
||||
ULONG CcFastMdlReadNotPossible;
|
||||
ULONG CcFastReadNotPossible;
|
||||
ULONG CcFastReadWait;
|
||||
ULONG CcFastReadNoWait;
|
||||
ULONG CcFastReadResourceMiss;
|
||||
|
||||
extern FAST_MUTEX CcCacheViewLock;
|
||||
extern LIST_ENTRY CcFreeCacheViewListHead;
|
||||
extern LIST_ENTRY CcInUseCacheViewListHead;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS NTAPI MmMapViewInSystemCache (PCACHE_VIEW);
|
||||
|
||||
|
||||
VOID NTAPI
|
||||
CcInitCacheZeroPage (VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = MmRequestPageMemoryConsumer (MC_NPPOOL, TRUE, &CcZeroPage);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
DbgPrint ("Can't allocate CcZeroPage.\n");
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Status = MiZeroPage (CcZeroPage);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
DbgPrint ("Can't zero out CcZeroPage.\n");
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcCanIWrite (IN PFILE_OBJECT FileObject,
|
||||
IN ULONG BytesToWrite,
|
||||
IN BOOLEAN Wait,
|
||||
IN BOOLEAN Retrying)
|
||||
{
|
||||
/* Our cache is always ready for writes */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN NTAPI
|
||||
CcCopyRead (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
|
||||
ULONG Index;
|
||||
PBCB Bcb;
|
||||
LARGE_INTEGER Offset;
|
||||
PLIST_ENTRY entry;
|
||||
PCACHE_VIEW current = NULL;
|
||||
ULONG CurrentLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("CcCopyRead(FileObject 0x%p, FileOffset %I64x, "
|
||||
"Length %d, Wait %d, Buffer 0x%p, IoStatus 0x%p)\n",
|
||||
FileObject, FileOffset->QuadPart, Length, Wait, Buffer, IoStatus);
|
||||
|
||||
|
||||
if (!Wait)
|
||||
{
|
||||
IoStatus->Information = 0;
|
||||
IoStatus->Status = STATUS_UNSUCCESSFUL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IoStatus->Information = Length;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
if (FileOffset->QuadPart + Length > Bcb->FileSizes.FileSize.QuadPart)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof (Bcb->CacheView) / sizeof (Bcb->CacheView[0]) * CACHE_VIEW_SIZE)
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Offset = *FileOffset;
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
while (Length)
|
||||
{
|
||||
Index = Offset.QuadPart / CACHE_VIEW_SIZE;
|
||||
if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb)
|
||||
{
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsListEmpty (&CcFreeCacheViewListHead))
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
entry = CcFreeCacheViewListHead.Flink;
|
||||
while (entry != &CcFreeCacheViewListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD (entry, CACHE_VIEW, ListEntry);
|
||||
entry = entry->Flink;
|
||||
if (current->Bcb == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry == &CcFreeCacheViewListHead)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
if (current->Bcb)
|
||||
{
|
||||
current->Bcb->CacheView[current->SectionData.ViewOffset / CACHE_VIEW_SIZE] = NULL;
|
||||
}
|
||||
Bcb->CacheView[Index] = current;
|
||||
|
||||
|
||||
if (Bcb->CacheView[Index]->Bcb != NULL)
|
||||
{
|
||||
DPRINT1 ("%x\n", Bcb->CacheView[Index]->Bcb);
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount = 1;
|
||||
Bcb->CacheView[Index]->Bcb = Bcb;
|
||||
Bcb->CacheView[Index]->SectionData.ViewOffset = Index * CACHE_VIEW_SIZE;
|
||||
Bcb->CacheView[Index]->SectionData.Section = Bcb->Section;
|
||||
Bcb->CacheView[Index]->SectionData.Segment = Bcb->Section->Segment;
|
||||
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
|
||||
Status = MmMapViewInSystemCache (Bcb->CacheView[Index]);
|
||||
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
if (Offset.QuadPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
if (Length > CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
CurrentLength = CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length;
|
||||
}
|
||||
memcpy (Buffer,
|
||||
(PVOID) ((ULONG_PTR) Bcb->CacheView[Index]->BaseAddress + Offset.u.LowPart % CACHE_VIEW_SIZE), CurrentLength);
|
||||
Buffer = (PVOID) ((ULONG_PTR) Buffer + CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length > CACHE_VIEW_SIZE ? CACHE_VIEW_SIZE : Length;
|
||||
memcpy (Buffer, Bcb->CacheView[Index]->BaseAddress, CurrentLength);
|
||||
Buffer = (PVOID) ((ULONG_PTR) Buffer + CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
Bcb->CacheView[Index]->RefCount--;
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcFreeCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcCopyWrite (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Wait,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
|
||||
ULONG Index;
|
||||
PBCB Bcb;
|
||||
LARGE_INTEGER Offset;
|
||||
PLIST_ENTRY entry;
|
||||
PCACHE_VIEW current = NULL;
|
||||
ULONG CurrentLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("CcCopyWrite(FileObject 0x%p, FileOffset %I64x, "
|
||||
"Length %d, Wait %d, Buffer 0x%p)\n", FileObject, FileOffset->QuadPart, Length, Wait, Buffer);
|
||||
|
||||
if (!Wait)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
if (FileOffset->QuadPart + Length > Bcb->FileSizes.FileSize.QuadPart)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof (Bcb->CacheView) / sizeof (Bcb->CacheView[0]) * CACHE_VIEW_SIZE)
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Offset = *FileOffset;
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
while (Length)
|
||||
{
|
||||
Index = Offset.QuadPart / CACHE_VIEW_SIZE;
|
||||
if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb)
|
||||
{
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsListEmpty (&CcFreeCacheViewListHead))
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
entry = CcFreeCacheViewListHead.Flink;
|
||||
while (entry != &CcFreeCacheViewListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD (entry, CACHE_VIEW, ListEntry);
|
||||
entry = entry->Flink;
|
||||
if (current->Bcb == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry == &CcFreeCacheViewListHead)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
if (current->Bcb)
|
||||
{
|
||||
current->Bcb->CacheView[current->SectionData.ViewOffset / CACHE_VIEW_SIZE] = NULL;
|
||||
}
|
||||
|
||||
Bcb->CacheView[Index] = current;
|
||||
|
||||
if (Bcb->CacheView[Index]->Bcb != NULL)
|
||||
{
|
||||
DPRINT1 ("%x\n", Bcb->CacheView[Index]->Bcb);
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount = 1;
|
||||
Bcb->CacheView[Index]->Bcb = Bcb;
|
||||
Bcb->CacheView[Index]->SectionData.ViewOffset = Index * CACHE_VIEW_SIZE;
|
||||
Bcb->CacheView[Index]->SectionData.Section = Bcb->Section;
|
||||
Bcb->CacheView[Index]->SectionData.Segment = Bcb->Section->Segment;
|
||||
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
|
||||
Status = MmMapViewInSystemCache (Bcb->CacheView[Index]);
|
||||
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
if (Offset.QuadPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
if (Length > CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
CurrentLength = CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length;
|
||||
}
|
||||
memcpy ((PVOID) ((ULONG_PTR) Bcb->CacheView[Index]->BaseAddress + Offset.u.LowPart % CACHE_VIEW_SIZE),
|
||||
Buffer, CurrentLength);
|
||||
Buffer = (PVOID) ((ULONG_PTR) Buffer + CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length > CACHE_VIEW_SIZE ? CACHE_VIEW_SIZE : Length;
|
||||
memcpy (Bcb->CacheView[Index]->BaseAddress, Buffer, CurrentLength);
|
||||
Buffer = (PVOID) ((ULONG_PTR) Buffer + CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
Bcb->CacheView[Index]->RefCount--;
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcFreeCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcDeferWrite (IN PFILE_OBJECT FileObject,
|
||||
IN PCC_POST_DEFERRED_WRITE PostRoutine,
|
||||
IN PVOID Context1,
|
||||
IN PVOID Context2,
|
||||
IN ULONG BytesToWrite,
|
||||
IN BOOLEAN Retrying)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcFastCopyRead (IN PFILE_OBJECT FileObject,
|
||||
IN ULONG FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG PageCount,
|
||||
OUT PVOID Buffer,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcFastCopyWrite (IN PFILE_OBJECT FileObject,
|
||||
IN ULONG FileOffset,
|
||||
IN ULONG Length,
|
||||
IN PVOID Buffer)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
CcWaitForCurrentLazyWriterActivity (VOID)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcZeroData (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER StartOffset,
|
||||
IN PLARGE_INTEGER EndOffset,
|
||||
IN BOOLEAN Wait)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER WriteOffset;
|
||||
ULONG Length;
|
||||
ULONG CurrentLength;
|
||||
PMDL Mdl;
|
||||
ULONG i;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
KEVENT Event;
|
||||
LARGE_INTEGER Offset;
|
||||
ULONG Index;
|
||||
|
||||
DPRINT ("CcZeroData(FileObject 0x%p, StartOffset %I64x, EndOffset %I64x, "
|
||||
"Wait %d)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart, Wait);
|
||||
|
||||
Length = EndOffset->u.LowPart - StartOffset->u.LowPart;
|
||||
WriteOffset.QuadPart = StartOffset->QuadPart;
|
||||
|
||||
if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
|
||||
{
|
||||
/* File is not cached */
|
||||
|
||||
Mdl = alloca (MmSizeOfMdl (NULL, MAX_ZERO_LENGTH));
|
||||
|
||||
while (Length > 0)
|
||||
{
|
||||
if (Length + WriteOffset.u.LowPart % PAGE_SIZE > MAX_ZERO_LENGTH)
|
||||
{
|
||||
CurrentLength = MAX_ZERO_LENGTH - WriteOffset.u.LowPart % PAGE_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length;
|
||||
}
|
||||
MmInitializeMdl (Mdl, (PVOID) WriteOffset.u.LowPart, CurrentLength);
|
||||
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
||||
for (i = 0; i < ((Mdl->Size - sizeof (MDL)) / sizeof (ULONG)); i++)
|
||||
{
|
||||
((PPFN_TYPE) (Mdl + 1))[i] = CcZeroPage;
|
||||
}
|
||||
KeInitializeEvent (&Event, NotificationEvent, FALSE);
|
||||
Status = IoSynchronousPageWrite (FileObject, Mdl, &WriteOffset, &Event, &Iosb);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject (&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = Iosb.Status;
|
||||
}
|
||||
MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
WriteOffset.QuadPart += CurrentLength;
|
||||
Length -= CurrentLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* File is cached */
|
||||
PBCB Bcb;
|
||||
PCACHE_VIEW current = NULL;
|
||||
PLIST_ENTRY entry;
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
if (!Wait)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (EndOffset->QuadPart > Bcb->FileSizes.FileSize.QuadPart)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof (Bcb->CacheView) / sizeof (Bcb->CacheView[0]) * CACHE_VIEW_SIZE)
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Offset = *StartOffset;
|
||||
Length = EndOffset->QuadPart - StartOffset->QuadPart;
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
while (Length)
|
||||
{
|
||||
Index = Offset.QuadPart / CACHE_VIEW_SIZE;
|
||||
if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb)
|
||||
{
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsListEmpty (&CcFreeCacheViewListHead))
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
entry = CcFreeCacheViewListHead.Flink;
|
||||
while (entry != &CcFreeCacheViewListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD (entry, CACHE_VIEW, ListEntry);
|
||||
entry = entry->Flink;
|
||||
if (current->Bcb == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry == &CcFreeCacheViewListHead)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Bcb->CacheView[Index] = current;
|
||||
|
||||
if (Bcb->CacheView[Index]->Bcb != NULL)
|
||||
{
|
||||
DPRINT1 ("%x\n", Bcb->CacheView[Index]->Bcb);
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount = 1;
|
||||
Bcb->CacheView[Index]->Bcb = Bcb;
|
||||
Bcb->CacheView[Index]->SectionData.ViewOffset = Index * CACHE_VIEW_SIZE;
|
||||
Bcb->CacheView[Index]->SectionData.Section = Bcb->Section;
|
||||
Bcb->CacheView[Index]->SectionData.Segment = Bcb->Section->Segment;
|
||||
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
|
||||
Status = MmMapViewInSystemCache (Bcb->CacheView[Index]);
|
||||
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
if (Offset.QuadPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
if (Length > CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE)
|
||||
{
|
||||
CurrentLength = CACHE_VIEW_SIZE - Offset.u.LowPart % CACHE_VIEW_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length;
|
||||
}
|
||||
memset ((PVOID) ((ULONG_PTR) Bcb->CacheView[Index]->BaseAddress + Offset.u.LowPart % CACHE_VIEW_SIZE), 0,
|
||||
CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLength = Length > CACHE_VIEW_SIZE ? CACHE_VIEW_SIZE : Length;
|
||||
memset (Bcb->CacheView[Index]->BaseAddress, 0, CurrentLength);
|
||||
Length -= CurrentLength;
|
||||
Offset.QuadPart += CurrentLength;
|
||||
}
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
Bcb->CacheView[Index]->RefCount--;
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcFreeCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
189
cc/fs.c
189
cc/fs.c
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/fs.c
|
||||
* PURPOSE: Implements cache managers functions useful for File Systems
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#ifndef ROUND_DOWN
|
||||
#define ROUND_DOWN(X,Y) ((X) & ~((Y) - 1))
|
||||
#endif
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
extern PCACHE_VIEW CcCacheViewArray;
|
||||
extern ULONG CcCacheViewArrayCount;
|
||||
extern FAST_MUTEX CcCacheViewLock;
|
||||
|
||||
NTSTATUS NTAPI MmUnmapViewInSystemCache (PCACHE_VIEW);
|
||||
|
||||
NTSTATUS NTAPI MmChangeSectionSize (PSECTION_OBJECT Section, PLARGE_INTEGER NewMaxSize);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
LARGE_INTEGER NTAPI
|
||||
CcGetDirtyPages (IN PVOID LogHandle,
|
||||
IN PDIRTY_PAGE_ROUTINE DirtyPageRoutine,
|
||||
IN PVOID Context1,
|
||||
IN PVOID Context2)
|
||||
{
|
||||
LARGE_INTEGER i;
|
||||
UNIMPLEMENTED;
|
||||
i.QuadPart = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PFILE_OBJECT NTAPI
|
||||
CcGetFileObjectFromBcb (IN PVOID Bcb)
|
||||
{
|
||||
PINTERNAL_BCB iBcb = (PINTERNAL_BCB) Bcb;
|
||||
return iBcb->Bcb->FileObject;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
LARGE_INTEGER NTAPI
|
||||
CcGetLsnForFileObject (IN PFILE_OBJECT FileObject,
|
||||
OUT PLARGE_INTEGER OldestLsn OPTIONAL)
|
||||
{
|
||||
LARGE_INTEGER i;
|
||||
UNIMPLEMENTED;
|
||||
i.QuadPart = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcIsThereDirtyData (IN PVPB Vpb)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcPurgeCacheSection (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
|
||||
IN PLARGE_INTEGER FileOffset OPTIONAL,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN UninitializeCacheMaps)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetFileSizes (IN PFILE_OBJECT FileObject,
|
||||
IN PCC_FILE_SIZES FileSizes)
|
||||
{
|
||||
PBCB Bcb;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
|
||||
DPRINT ("CcSetFileSizes(FileObject 0x%p, FileSizes 0x%p)\n", FileObject, FileSizes);
|
||||
DPRINT ("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
|
||||
(ULONG) FileSizes->AllocationSize.QuadPart,
|
||||
(ULONG) FileSizes->FileSize.QuadPart, (ULONG) FileSizes->ValidDataLength.QuadPart);
|
||||
DPRINT ("%wZ\n", &FileObject->FileName);
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Bcb == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DPRINT ("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
|
||||
(ULONG) Bcb->FileSizes.AllocationSize.QuadPart,
|
||||
(ULONG) Bcb->FileSizes.FileSize.QuadPart, (ULONG) Bcb->FileSizes.ValidDataLength.QuadPart);
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
DPRINT ("%d\n", Bcb->FileSizes.FileSize.u.LowPart);
|
||||
|
||||
for (i = ROUND_DOWN (FileSizes->AllocationSize.QuadPart, CACHE_VIEW_SIZE) / CACHE_VIEW_SIZE;
|
||||
i < ROUND_UP (Bcb->FileSizes.AllocationSize.QuadPart, CACHE_VIEW_SIZE) / CACHE_VIEW_SIZE; i++)
|
||||
{
|
||||
if (Bcb->CacheView[i] != NULL)
|
||||
{
|
||||
if (Bcb->CacheView[i]->Bcb != Bcb)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
if (Bcb->CacheView[i]->RefCount > 0)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Status = MmUnmapViewInSystemCache (Bcb->CacheView[i]);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[i]->RefCount = 0;
|
||||
Bcb->CacheView[i]->Bcb = NULL;
|
||||
Bcb->CacheView[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < CcCacheViewArrayCount; i++)
|
||||
{
|
||||
if (CcCacheViewArray[i].Bcb == Bcb)
|
||||
{
|
||||
if (PAGE_ROUND_UP (FileSizes->AllocationSize.QuadPart) <= CcCacheViewArray[i].SectionData.ViewOffset ||
|
||||
(PAGE_ROUND_UP (FileSizes->AllocationSize.QuadPart) > CcCacheViewArray[i].SectionData.ViewOffset &&
|
||||
PAGE_ROUND_UP (FileSizes->AllocationSize.QuadPart) <=
|
||||
CcCacheViewArray[i].SectionData.ViewOffset + CACHE_VIEW_SIZE))
|
||||
|
||||
{
|
||||
if (CcCacheViewArray[i].RefCount > 0)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Status = MmUnmapViewInSystemCache (&CcCacheViewArray[i]);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
CcCacheViewArray[i].RefCount = 0;
|
||||
CcCacheViewArray[i].Bcb = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Status = MmChangeSectionSize ((PSECTION_OBJECT)Bcb->Section, &FileSizes->FileSize);
|
||||
Bcb->FileSizes = *FileSizes;
|
||||
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetLogHandleForFile (IN PFILE_OBJECT FileObject,
|
||||
IN PVOID LogHandle,
|
||||
IN PFLUSH_TO_LSN FlushToLsnRoutine)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
169
cc/mdl.c
169
cc/mdl.c
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/fs.c
|
||||
* PURPOSE: Implements MDL Cache Manager Functions
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlRead (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT PMDL * MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME INTERNAL
|
||||
* CcMdlReadCompleteDev@8
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
* MdlChain
|
||||
* DeviceObject
|
||||
*
|
||||
* RETURN VALUE
|
||||
* None.
|
||||
*
|
||||
* NOTE
|
||||
* Used by CcMdlReadComplete@8 and FsRtl
|
||||
*
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlReadCompleteDev (IN PMDL MdlChain,
|
||||
IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
PMDL Mdl;
|
||||
|
||||
/* Free MDLs */
|
||||
while ((Mdl = MdlChain))
|
||||
{
|
||||
MdlChain = Mdl->Next;
|
||||
MmUnlockPages (Mdl);
|
||||
IoFreeMdl (Mdl);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NAME EXPORTED
|
||||
* CcMdlReadComplete@8
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
*
|
||||
* RETURN VALUE
|
||||
* None.
|
||||
*
|
||||
* NOTE
|
||||
* From Bo Branten's ntifs.h v13.
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlReadComplete (IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject = NULL;
|
||||
PFAST_IO_DISPATCH FastDispatch;
|
||||
|
||||
/* Get Fast Dispatch Data */
|
||||
DeviceObject = IoGetRelatedDeviceObject (FileObject);
|
||||
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||
|
||||
/* Check if we support Fast Calls, and check this one */
|
||||
if (FastDispatch && FastDispatch->MdlReadComplete)
|
||||
{
|
||||
/* Use the fast path */
|
||||
FastDispatch->MdlReadComplete (FileObject, MdlChain, DeviceObject);
|
||||
}
|
||||
|
||||
/* Use slow path */
|
||||
CcMdlReadComplete2 (MdlChain, FileObject);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlWriteComplete (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject = NULL;
|
||||
PFAST_IO_DISPATCH FastDispatch;
|
||||
|
||||
/* Get Fast Dispatch Data */
|
||||
DeviceObject = IoGetRelatedDeviceObject (FileObject);
|
||||
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
|
||||
|
||||
/* Check if we support Fast Calls, and check this one */
|
||||
if (FastDispatch && FastDispatch->MdlWriteComplete)
|
||||
{
|
||||
/* Use the fast path */
|
||||
FastDispatch->MdlWriteComplete (FileObject, FileOffset, MdlChain, DeviceObject);
|
||||
}
|
||||
|
||||
/* Use slow path */
|
||||
CcMdlWriteComplete2 (FileObject, FileOffset, MdlChain);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlReadComplete2 (IN PMDL MemoryDescriptorList,
|
||||
IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlWriteComplete2 (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcMdlWriteAbort (IN PFILE_OBJECT FileObject,
|
||||
IN PMDL MdlChain)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcPrepareMdlWrite (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
OUT PMDL * MdlChain,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
313
cc/pin.c
313
cc/pin.c
@@ -1,313 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/pin.c
|
||||
* PURPOSE: Implements cache managers pinning interface
|
||||
*
|
||||
* PROGRAMMERS:
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
extern NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
||||
|
||||
extern FAST_MUTEX CcCacheViewLock;
|
||||
extern LIST_ENTRY CcFreeCacheViewListHead;
|
||||
extern LIST_ENTRY CcInUseCacheViewListHead;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS NTAPI MmMapViewInSystemCache (PCACHE_VIEW);
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcMapData (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID * piBcb,
|
||||
OUT PVOID * pBuffer)
|
||||
{
|
||||
PINTERNAL_BCB iBcb;
|
||||
PBCB Bcb;
|
||||
ULONG Index;
|
||||
NTSTATUS Status;
|
||||
PLIST_ENTRY entry;
|
||||
PCACHE_VIEW current = NULL;
|
||||
|
||||
DPRINT ("CcMapData(FileObject 0x%p, FileOffset %I64x, Length %d,"
|
||||
" pBcb 0x%p, pBuffer 0x%p)\n", FileObject, FileOffset->QuadPart, Length, piBcb, pBuffer);
|
||||
|
||||
ASSERT (FileObject);
|
||||
ASSERT (FileObject->SectionObjectPointer);
|
||||
ASSERT (FileObject->SectionObjectPointer->SharedCacheMap);
|
||||
ASSERT (FileOffset);
|
||||
ASSERT (piBcb);
|
||||
ASSERT (pBuffer);
|
||||
//ASSERT (Flags & MAP_WAIT);
|
||||
|
||||
if (!(Flags & MAP_WAIT))
|
||||
{
|
||||
DPRINT1("Reading without MAP_WAIT flag!\n");
|
||||
//*piBcb = NULL;
|
||||
//*pBuffer = NULL;
|
||||
//return FALSE;
|
||||
}
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
|
||||
if (FileOffset->QuadPart + Length > Bcb->FileSizes.AllocationSize.QuadPart)
|
||||
{
|
||||
DPRINT ("%d %I64d %I64d\n", Length, FileOffset->QuadPart + Length, Bcb->FileSizes.AllocationSize.QuadPart);
|
||||
// KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
if (FileOffset->QuadPart + Length - ROUND_DOWN (FileOffset->QuadPart, CACHE_VIEW_SIZE) > CACHE_VIEW_SIZE)
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Bcb->FileSizes.AllocationSize.QuadPart > sizeof (Bcb->CacheView) / sizeof (Bcb->CacheView[0]) * CACHE_VIEW_SIZE)
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
Index = FileOffset->QuadPart / CACHE_VIEW_SIZE;
|
||||
if (Bcb->CacheView[Index] && Bcb->CacheView[Index]->Bcb == Bcb)
|
||||
{
|
||||
if (Bcb->CacheView[Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsListEmpty (&CcFreeCacheViewListHead))
|
||||
{
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
entry = CcFreeCacheViewListHead.Flink;
|
||||
while (entry != &CcFreeCacheViewListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD (entry, CACHE_VIEW, ListEntry);
|
||||
entry = entry->Flink;
|
||||
if (current->Bcb == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry == &CcFreeCacheViewListHead)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Bcb->CacheView[Index] = current;
|
||||
|
||||
if (Bcb->CacheView[Index]->Bcb != NULL)
|
||||
{
|
||||
DPRINT1 ("%x\n", Bcb->CacheView[Index]->Bcb);
|
||||
/* not implemented */
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[Index]->RefCount = 1;
|
||||
Bcb->CacheView[Index]->Bcb = Bcb;
|
||||
Bcb->CacheView[Index]->SectionData.ViewOffset = Index * CACHE_VIEW_SIZE;
|
||||
Bcb->CacheView[Index]->SectionData.Section = Bcb->Section;
|
||||
Bcb->CacheView[Index]->SectionData.Segment = Bcb->Section->Segment;
|
||||
|
||||
RemoveEntryList (&Bcb->CacheView[Index]->ListEntry);
|
||||
InsertHeadList (&CcInUseCacheViewListHead, &Bcb->CacheView[Index]->ListEntry);
|
||||
|
||||
Status = MmMapViewInSystemCache (Bcb->CacheView[Index]);
|
||||
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
|
||||
iBcb = ExAllocateFromNPagedLookasideList (&iBcbLookasideList);
|
||||
if (iBcb == NULL)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
memset (iBcb, 0, sizeof (INTERNAL_BCB));
|
||||
|
||||
iBcb->Bcb = Bcb;
|
||||
iBcb->Index = Index;
|
||||
|
||||
*piBcb = iBcb;
|
||||
*pBuffer = (PVOID) ((ULONG_PTR) Bcb->CacheView[Index]->BaseAddress +
|
||||
(ULONG_PTR) (FileOffset->QuadPart - Bcb->CacheView[Index]->SectionData.ViewOffset));
|
||||
|
||||
DPRINT ("CcMapData() done\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcPinMappedData (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID * Bcb)
|
||||
{
|
||||
/* no-op for current implementation. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcPinRead (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID * Bcb,
|
||||
OUT PVOID * Buffer)
|
||||
{
|
||||
if (CcMapData (FileObject, FileOffset, Length, Flags, Bcb, Buffer))
|
||||
{
|
||||
if (CcPinMappedData (FileObject, FileOffset, Length, Flags, Bcb))
|
||||
return TRUE;
|
||||
else
|
||||
CcUnpinData (Bcb);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOLEAN NTAPI
|
||||
CcPreparePinWrite (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER FileOffset,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Zero,
|
||||
IN ULONG Flags,
|
||||
OUT PVOID * Bcb,
|
||||
OUT PVOID * Buffer)
|
||||
{
|
||||
/*
|
||||
* FIXME: This is function is similar to CcPinRead, but doesn't
|
||||
* read the data if they're not present. Instead it should just
|
||||
* prepare the cache segments and zero them out if Zero == TRUE.
|
||||
*
|
||||
* For now calling CcPinRead is better than returning error or
|
||||
* just having UNIMPLEMENTED here.
|
||||
*/
|
||||
return CcPinRead (FileObject, FileOffset, Length, Flags, Bcb, Buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcSetDirtyPinnedData (IN PVOID Bcb,
|
||||
IN PLARGE_INTEGER Lsn)
|
||||
{
|
||||
// PINTERNAL_BCB iBcb = Bcb;
|
||||
// iBcb->Dirty = TRUE;
|
||||
// UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcUnpinData (IN PVOID _iBcb)
|
||||
{
|
||||
PINTERNAL_BCB iBcb = _iBcb;
|
||||
|
||||
DPRINT ("CcUnpinData(%x)\n", _iBcb);
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
iBcb->Bcb->CacheView[iBcb->Index]->RefCount--;
|
||||
if (iBcb->Bcb->CacheView[iBcb->Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&iBcb->Bcb->CacheView[iBcb->Index]->ListEntry);
|
||||
InsertHeadList (&CcFreeCacheViewListHead, &iBcb->Bcb->CacheView[iBcb->Index]->ListEntry);
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
ExFreeToNPagedLookasideList (&iBcbLookasideList, iBcb);
|
||||
|
||||
DPRINT ("CcUnpinData done\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcUnpinDataForThread (IN PVOID Bcb,
|
||||
IN ERESOURCE_THREAD ResourceThreadId)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcRepinBcb (IN PVOID Bcb)
|
||||
{
|
||||
#if 0
|
||||
PINTERNAL_BCB iBcb = Bcb;
|
||||
// iBcb->RefCount++;
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
iBcb->Bcb->CacheView[iBcb->Index]->RefCount++;
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcUnpinRepinnedBcb (IN PVOID Bcb,
|
||||
IN BOOLEAN WriteThrough,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
#if 0
|
||||
PINTERNAL_BCB iBcb = Bcb;
|
||||
|
||||
DPRINT ("CcUnpinRepinnedBcb(%x)\n", Bcb);
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
iBcb->Bcb->CacheView[iBcb->Index]->RefCount--;
|
||||
if (iBcb->Bcb->CacheView[iBcb->Index]->RefCount == 0)
|
||||
{
|
||||
RemoveEntryList (&iBcb->Bcb->CacheView[iBcb->Index]->ListEntry);
|
||||
InsertHeadList (&CcFreeCacheViewListHead, &iBcb->Bcb->CacheView[iBcb->Index]->ListEntry);
|
||||
}
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
ExFreeToNPagedLookasideList (&iBcbLookasideList, iBcb);
|
||||
#endif
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT ("CcUnpinRepinnedBcb done\n");
|
||||
}
|
287
cc/view.c
287
cc/view.c
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/cc/view.c
|
||||
* PURPOSE: Cache manager
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#ifdef ROUND_UP
|
||||
#undef ROUND_UP
|
||||
#endif
|
||||
#ifdef ROUND_DOWN
|
||||
#undef ROUND_DOWN
|
||||
#endif
|
||||
|
||||
#define ROUND_UP(N, S) (((N) + (S) - 1) & ~((S) - 1))
|
||||
#define ROUND_DOWN(N, S) ((N) & ~((S) - 1))
|
||||
|
||||
NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
||||
static NPAGED_LOOKASIDE_LIST BcbLookasideList;
|
||||
|
||||
PVOID CcCacheViewBase;
|
||||
ULONG CcCacheViewArrayCount;
|
||||
PCACHE_VIEW CcCacheViewArray;
|
||||
FAST_MUTEX CcCacheViewLock;
|
||||
LIST_ENTRY CcFreeCacheViewListHead;
|
||||
LIST_ENTRY CcInUseCacheViewListHead;
|
||||
PMEMORY_AREA CcCacheViewMemoryArea;
|
||||
|
||||
NTSTATUS NTAPI MmCreateDataFileSection (PSECTION_OBJECT * SectionObject,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
PLARGE_INTEGER UMaximumSize,
|
||||
ULONG SectionPageProtection,
|
||||
ULONG AllocationAttributes,
|
||||
PFILE_OBJECT FileObject,
|
||||
BOOLEAN CacheManager);
|
||||
|
||||
NTSTATUS NTAPI MmUnmapViewInSystemCache (PCACHE_VIEW);
|
||||
|
||||
NTSTATUS MmFlushDataFileSection (PSECTION_OBJECT Section, PLARGE_INTEGER StartOffset, ULONG Length);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID NTAPI
|
||||
CcFlushCache (IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
|
||||
IN PLARGE_INTEGER FileOffset OPTIONAL,
|
||||
IN ULONG Length,
|
||||
OUT PIO_STATUS_BLOCK IoStatus)
|
||||
{
|
||||
PBCB Bcb;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT ("CcFlushCache(SectionObjectPointers 0x%p, FileOffset 0x%p, Length %d, IoStatus 0x%p)\n",
|
||||
SectionObjectPointers, FileOffset, Length, IoStatus);
|
||||
|
||||
if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
|
||||
{
|
||||
Bcb = (PBCB) SectionObjectPointers->SharedCacheMap;
|
||||
ASSERT (Bcb);
|
||||
|
||||
Status = MmFlushDataFileSection ((PSECTION_OBJECT)Bcb->Section, FileOffset, Length);
|
||||
}
|
||||
if (IoStatus)
|
||||
{
|
||||
IoStatus->Status = Status;
|
||||
IoStatus->Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PFILE_OBJECT NTAPI
|
||||
CcGetFileObjectFromSectionPtrs (IN PSECTION_OBJECT_POINTERS SectionObjectPointers)
|
||||
{
|
||||
PBCB Bcb;
|
||||
if (SectionObjectPointers && SectionObjectPointers->SharedCacheMap)
|
||||
{
|
||||
Bcb = (PBCB) SectionObjectPointers->SharedCacheMap;
|
||||
ASSERT (Bcb);
|
||||
return Bcb->FileObject;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CcTrimMemory (ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
||||
{
|
||||
DPRINT1("Trim function for cache memory is not implemented yet.\n");
|
||||
|
||||
(*NrFreedPages) = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID INIT_FUNCTION NTAPI
|
||||
CcInitView (VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||
ULONG i;
|
||||
ULONG Size;
|
||||
PVOID Base;
|
||||
|
||||
DPRINT ("CcInitView()\n");
|
||||
|
||||
ExInitializeFastMutex (&CcCacheViewLock);
|
||||
|
||||
ExInitializeNPagedLookasideList (&iBcbLookasideList, NULL, NULL, 0, sizeof (INTERNAL_BCB), TAG_IBCB, 20);
|
||||
ExInitializeNPagedLookasideList (&BcbLookasideList, NULL, NULL, 0, sizeof (BCB), TAG_BCB, 20);
|
||||
|
||||
InitializeListHead (&CcFreeCacheViewListHead);
|
||||
InitializeListHead (&CcInUseCacheViewListHead);
|
||||
|
||||
BoundaryAddressMultiple.QuadPart = 0LL;
|
||||
|
||||
Size = MmSystemRangeStart >= (PVOID) 0xC0000000 ? 0x18000000 : 0x20000000;
|
||||
CcCacheViewBase = (PVOID) (0xF0000000 - Size);
|
||||
MmLockAddressSpace (MmGetKernelAddressSpace ());
|
||||
|
||||
Status = MmCreateMemoryArea (MmGetKernelAddressSpace (),
|
||||
MEMORY_AREA_CACHE_SEGMENT,
|
||||
&CcCacheViewBase, Size, 0, &CcCacheViewMemoryArea, FALSE, FALSE, BoundaryAddressMultiple);
|
||||
MmUnlockAddressSpace (MmGetKernelAddressSpace ());
|
||||
DPRINT ("CcCacheViewBase: %x\n", CcCacheViewBase);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
CcCacheViewArray = ExAllocatePool (NonPagedPool, sizeof (CACHE_VIEW) * (Size / CACHE_VIEW_SIZE));
|
||||
if (CcCacheViewArray == NULL)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
Base = CcCacheViewBase;
|
||||
CcCacheViewArrayCount = Size / CACHE_VIEW_SIZE;
|
||||
for (i = 0; i < CcCacheViewArrayCount; i++)
|
||||
{
|
||||
CcCacheViewArray[i].BaseAddress = Base;
|
||||
CcCacheViewArray[i].RefCount = 0;
|
||||
CcCacheViewArray[i].Bcb = NULL;
|
||||
CcCacheViewArray[i].SectionData.ViewOffset = 0;
|
||||
InsertTailList (&CcFreeCacheViewListHead, &CcCacheViewArray[i].ListEntry);
|
||||
Base = (PVOID) ((ULONG_PTR) Base + CACHE_VIEW_SIZE);
|
||||
}
|
||||
|
||||
MmInitializeMemoryConsumer(MC_CACHE, CcTrimMemory);
|
||||
CcInitCacheZeroPage ();
|
||||
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
CcInitializeCacheMap (IN PFILE_OBJECT FileObject,
|
||||
IN PCC_FILE_SIZES FileSizes,
|
||||
IN BOOLEAN PinAccess,
|
||||
IN PCACHE_MANAGER_CALLBACKS CallBacks,
|
||||
IN PVOID LazyWriterContext)
|
||||
{
|
||||
PBCB Bcb;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("CcInitializeCacheMap(), %wZ\n", &FileObject->FileName);
|
||||
DPRINT ("%I64x (%I64d)\n", FileSizes->FileSize.QuadPart, FileSizes->FileSize.QuadPart);
|
||||
|
||||
ASSERT (FileObject);
|
||||
ASSERT (FileSizes);
|
||||
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Bcb == NULL)
|
||||
{
|
||||
Bcb = ExAllocateFromNPagedLookasideList (&BcbLookasideList);
|
||||
if (Bcb == NULL)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
memset (Bcb, 0, sizeof (BCB));
|
||||
|
||||
Bcb->FileObject = FileObject;
|
||||
Bcb->FileSizes = *FileSizes;
|
||||
Bcb->PinAccess = PinAccess;
|
||||
Bcb->CallBacks = CallBacks;
|
||||
Bcb->LazyWriterContext = LazyWriterContext;
|
||||
Bcb->RefCount = 0;
|
||||
|
||||
DPRINT ("%x %x\n", FileObject, FileSizes->FileSize.QuadPart);
|
||||
|
||||
Status = MmCreateDataFileSection ((PSECTION_OBJECT*)&Bcb->Section,
|
||||
STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE,
|
||||
NULL, &Bcb->FileSizes.FileSize, PAGE_READWRITE, SEC_COMMIT, Bcb->FileObject, TRUE);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
DPRINT1 ("%x\n", Status);
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = Bcb;
|
||||
}
|
||||
|
||||
if (FileObject->PrivateCacheMap == NULL)
|
||||
{
|
||||
FileObject->PrivateCacheMap = Bcb;
|
||||
Bcb->RefCount++;
|
||||
}
|
||||
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
DPRINT ("CcInitializeCacheMap() done\n");
|
||||
}
|
||||
|
||||
BOOLEAN NTAPI
|
||||
CcUninitializeCacheMap (IN PFILE_OBJECT FileObject,
|
||||
IN PLARGE_INTEGER TruncateSize OPTIONAL,
|
||||
IN PCACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent OPTIONAL)
|
||||
{
|
||||
PBCB Bcb;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("CcUninitializeCacheMap(), %wZ\n", &FileObject->FileName);
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||
if (Bcb)
|
||||
{
|
||||
if (FileObject->PrivateCacheMap == Bcb)
|
||||
{
|
||||
Bcb->RefCount--;
|
||||
FileObject->PrivateCacheMap = NULL;
|
||||
}
|
||||
if (Bcb->RefCount == 0)
|
||||
{
|
||||
Bcb->RefCount++;
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
MmFlushDataFileSection ((PSECTION_OBJECT)Bcb->Section, NULL, 0);
|
||||
ExAcquireFastMutex (&CcCacheViewLock);
|
||||
Bcb->RefCount--;
|
||||
if (Bcb->RefCount == 0)
|
||||
{
|
||||
for (i = 0; i < ROUND_UP (Bcb->FileSizes.AllocationSize.QuadPart, CACHE_VIEW_SIZE) / CACHE_VIEW_SIZE; i++)
|
||||
{
|
||||
if (Bcb->CacheView[i] && Bcb->CacheView[i]->Bcb == Bcb)
|
||||
{
|
||||
if (Bcb->CacheView[i]->RefCount > 0)
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Status = MmUnmapViewInSystemCache (Bcb->CacheView[i]);
|
||||
if (!NT_SUCCESS (Status))
|
||||
{
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
}
|
||||
Bcb->CacheView[i]->RefCount = 0;
|
||||
Bcb->CacheView[i]->Bcb = NULL;
|
||||
Bcb->CacheView[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT ("%x\n", Bcb->Section);
|
||||
ObDereferenceObject (Bcb->Section);
|
||||
FileObject->SectionObjectPointer->SharedCacheMap = NULL;
|
||||
ExFreeToNPagedLookasideList (&BcbLookasideList, Bcb);
|
||||
}
|
||||
}
|
||||
}
|
||||
DPRINT ("CcUninitializeCacheMap() done, %wZ\n", &FileObject->FileName);
|
||||
ExReleaseFastMutex (&CcCacheViewLock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* EOF */
|
141
headers.patch
141
headers.patch
@@ -1,141 +0,0 @@
|
||||
Index: include/reactos/exeformat.h
|
||||
===================================================================
|
||||
--- include/reactos/exeformat.h (revision 34037)
|
||||
+++ include/reactos/exeformat.h (working copy)
|
||||
@@ -35,6 +35,7 @@
|
||||
typedef NTSTATUS (NTAPI * PEXEFMT_CB_READ_FILE)
|
||||
(
|
||||
IN PVOID File,
|
||||
+ ULONG SectorSize,
|
||||
IN PLARGE_INTEGER Offset,
|
||||
IN ULONG Length,
|
||||
OUT PVOID * Data,
|
||||
Index: ntoskrnl/include/internal/mm.h
|
||||
===================================================================
|
||||
--- ntoskrnl/include/internal/mm.h (revision 34040)
|
||||
+++ ntoskrnl/include/internal/mm.h (working copy)
|
||||
@@ -187,6 +187,9 @@
|
||||
ULONG Flags;
|
||||
ULONG Characteristics;
|
||||
BOOLEAN WriteCopy;
|
||||
+ LIST_ENTRY ListEntry;
|
||||
+ ULONG BytesPerSector;
|
||||
+ PFILE_OBJECT FileObject;
|
||||
} MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
|
||||
|
||||
typedef struct _MM_IMAGE_SECTION_OBJECT
|
||||
@@ -203,6 +206,10 @@
|
||||
BOOLEAN Executable;
|
||||
ULONG NrSegments;
|
||||
ULONG ImageSize;
|
||||
+ ULONG RefCount;
|
||||
+ LIST_ENTRY ListEntry;
|
||||
+ PFILE_OBJECT FileObject;
|
||||
+ ULONG BytesPerSector;
|
||||
PMM_SECTION_SEGMENT Segments;
|
||||
} MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
|
||||
|
||||
@@ -221,6 +228,16 @@
|
||||
};
|
||||
} ROS_SECTION_OBJECT, *PROS_SECTION_OBJECT;
|
||||
|
||||
+typedef struct
|
||||
+{
|
||||
+ ROS_SECTION_OBJECT* Section;
|
||||
+ ULONG ViewOffset;
|
||||
+ LIST_ENTRY ViewListEntry;
|
||||
+ PMM_SECTION_SEGMENT Segment;
|
||||
+// BOOLEAN WriteCopyView;
|
||||
+ LIST_ENTRY RegionListHead;
|
||||
+} SECTION_DATA, *PSECTION_DATA;
|
||||
+
|
||||
typedef struct _MEMORY_AREA
|
||||
{
|
||||
PVOID StartingAddress;
|
||||
@@ -235,17 +252,10 @@
|
||||
ULONG PageOpCount;
|
||||
union
|
||||
{
|
||||
+ SECTION_DATA SectionData;
|
||||
struct
|
||||
{
|
||||
- ROS_SECTION_OBJECT* Section;
|
||||
- ULONG ViewOffset;
|
||||
- PMM_SECTION_SEGMENT Segment;
|
||||
- BOOLEAN WriteCopyView;
|
||||
LIST_ENTRY RegionListHead;
|
||||
- } SectionData;
|
||||
- struct
|
||||
- {
|
||||
- LIST_ENTRY RegionListHead;
|
||||
} VirtualMemoryData;
|
||||
} Data;
|
||||
} MEMORY_AREA, *PMEMORY_AREA;
|
||||
Index: ntoskrnl/include/internal/cc.h
|
||||
===================================================================
|
||||
--- ntoskrnl/include/internal/cc.h (revision 34040)
|
||||
+++ ntoskrnl/include/internal/cc.h (working copy)
|
||||
@@ -102,19 +102,29 @@
|
||||
LONG ActivePrefetches;
|
||||
} PFSN_PREFETCHER_GLOBALS, *PPFSN_PREFETCHER_GLOBALS;
|
||||
|
||||
+#define CACHE_VIEW_SIZE (128 * 1024) // 128kB
|
||||
+
|
||||
+struct _BCB;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ SECTION_DATA SectionData;
|
||||
+ PVOID BaseAddress;
|
||||
+ ULONG RefCount;
|
||||
+ struct _BCB* Bcb;
|
||||
+ LIST_ENTRY ListEntry;
|
||||
+} CACHE_VIEW, *PCACHE_VIEW;
|
||||
+
|
||||
typedef struct _BCB
|
||||
{
|
||||
- LIST_ENTRY BcbSegmentListHead;
|
||||
- LIST_ENTRY BcbRemoveListEntry;
|
||||
- BOOLEAN RemoveOnClose;
|
||||
- ULONG TimeStamp;
|
||||
PFILE_OBJECT FileObject;
|
||||
- ULONG CacheSegmentSize;
|
||||
- LARGE_INTEGER AllocationSize;
|
||||
- LARGE_INTEGER FileSize;
|
||||
- PCACHE_MANAGER_CALLBACKS Callbacks;
|
||||
- PVOID LazyWriteContext;
|
||||
- KSPIN_LOCK BcbLock;
|
||||
+ CC_FILE_SIZES FileSizes;
|
||||
+ BOOLEAN PinAccess;
|
||||
+ PCACHE_MANAGER_CALLBACKS CallBacks;
|
||||
+ PVOID LazyWriterContext;
|
||||
+ PCACHE_VIEW CacheView[2048];
|
||||
+ PVOID LargeCacheView;
|
||||
+ PROS_SECTION_OBJECT Section;
|
||||
ULONG RefCount;
|
||||
#if defined(DBG) || defined(KDBG)
|
||||
BOOLEAN Trace; /* enable extra trace output for this BCB and it's cache segments */
|
||||
@@ -159,8 +169,8 @@
|
||||
typedef struct _INTERNAL_BCB
|
||||
{
|
||||
PUBLIC_BCB PFCB;
|
||||
- PCACHE_SEGMENT CacheSegment;
|
||||
- BOOLEAN Dirty;
|
||||
+ PBCB Bcb;
|
||||
+ ULONG Index;
|
||||
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
|
||||
} INTERNAL_BCB, *PINTERNAL_BCB;
|
||||
|
||||
Index: drivers/filesystems/fastfat/vfat.h
|
||||
===================================================================
|
||||
--- drivers/filesystems/fastfat/vfat.h (revision 34037)
|
||||
+++ drivers/filesystems/fastfat/vfat.h (working copy)
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifdef __GNUC__
|
||||
#include <ccros.h>
|
||||
|
||||
-#define USE_ROS_CC_AND_FS
|
||||
+//#define USE_ROS_CC_AND_FS
|
||||
#else
|
||||
#define KEBUGCHECK KeBugCheck
|
||||
#define KEBUGCHECKEX KeBugCheckEx
|
2
reactos/.cvsignore
Normal file
2
reactos/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
errors
|
340
reactos/COPYING
Normal file
340
reactos/COPYING
Normal file
@@ -0,0 +1,340 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
14
reactos/CREDITS
Normal file
14
reactos/CREDITS
Normal file
@@ -0,0 +1,14 @@
|
||||
In no particular order
|
||||
|
||||
Rex Jolliff (rex@lvcablemodem.com)
|
||||
Boudewijn Dekker (ariadne@xs4all.nl)
|
||||
Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
Emanuele Aliberti (ea@iol.it)
|
||||
David Welch (welch@cwcom.net)
|
||||
Iwan Fatahi (i_fatahi@hotmail.com)
|
||||
Robert Bergkvist (fragdance@hotmail.com)
|
||||
Victor Kirhenshtein (sauros@iname.com)
|
||||
Jason Filby (jasonfilby@yahoo.com)
|
||||
Brian Palmer (brianp@sginet.com)
|
||||
Phillip Susi (phreak@iag.net)
|
||||
Paolo Pantaleo (paolopan@freemail.it)
|
12
reactos/ChangeLog
Normal file
12
reactos/ChangeLog
Normal file
@@ -0,0 +1,12 @@
|
||||
9/6/99: Implemented ZwOpenProcess
|
||||
Partially implemented killing other threads (possible memory
|
||||
leaks)
|
||||
Made a start on a proper implemention of APCs (based on
|
||||
article in NT insider)
|
||||
|
||||
8/12/98: Corrected bug in shell (Read two keypresses and assumed they
|
||||
where the key going up and down respectively)
|
||||
Corrected race in dpc handling
|
||||
Took out cleanup sections in ZwReadFile (now handled by the APC)
|
||||
Disabled broken code in kernel32
|
||||
|
31
reactos/INSTALL
Normal file
31
reactos/INSTALL
Normal file
@@ -0,0 +1,31 @@
|
||||
1. Build environment
|
||||
|
||||
To build the system you need either mingw32 installed on Windows or a
|
||||
mingw32 cross compiler running on unix.
|
||||
|
||||
2. Building
|
||||
|
||||
To build from Windows run make. To build from unix, edit rules.mak and change
|
||||
the PREFIX variable to the correct value for your cross-compiler, then run
|
||||
'make'.
|
||||
|
||||
3. Installation
|
||||
|
||||
Installation isn't yet automated, sorry. The system can only be installed on
|
||||
the first partition which must be formatted for DOS. Set up a directory
|
||||
structure like the following
|
||||
|
||||
make directories C:\reactos,C:\reactos\system,C:\reactos\system\drivers
|
||||
|
||||
Copy apps/shell/shell.exe to C:\reactos\system32
|
||||
Copy subsys/smss/smss.exe to C:\reactos\system32
|
||||
Copy services/dd/keyboard/keyboard.sys to C:\reactos\system32\drivers
|
||||
Copy services/dd/blue/blue.sys to C:\reactos\system32\drivers
|
||||
Copy lib/ntdll/ntdll.dll to C:\reactos\system32
|
||||
Copy lib/kernel32/kernel32.dll to C:\reactos\system32
|
||||
Copy lib/crtdll/crtdll.dll to C:\reactos\system32
|
||||
|
||||
The system can only be started from DOS. Copy the following files,
|
||||
services/dd/ide/ide.sys, services/fs/vfat/vfatfsd.sys and
|
||||
loaders/dos/loadros.com, to a suitable directory. The system can then be
|
||||
booted with the command 'loadros.com ide.sys vfatfsd.sys'.
|
280
reactos/Makefile
Normal file
280
reactos/Makefile
Normal file
@@ -0,0 +1,280 @@
|
||||
#
|
||||
# Global makefile
|
||||
#
|
||||
|
||||
#
|
||||
# Select your host
|
||||
#
|
||||
#HOST = mingw32-linux
|
||||
#HOST = djgpp-msdos
|
||||
#HOST = mingw32-windows
|
||||
|
||||
include rules.mak
|
||||
|
||||
#
|
||||
# Required to run the system
|
||||
#
|
||||
COMPONENTS = iface_native ntoskrnl
|
||||
DLLS = ntdll kernel32 crtdll advapi32 fmifs gdi32
|
||||
#DLLS = mingw32 user32
|
||||
SUBSYS = smss win32k
|
||||
#SUBSYS = csrss
|
||||
|
||||
#
|
||||
# Select the server(s) you want to build
|
||||
#
|
||||
SERVERS = win32
|
||||
# SERVERS = posix linux os2
|
||||
|
||||
#
|
||||
# Select the loader(s) you want to build
|
||||
#
|
||||
LOADERS = dos
|
||||
# LOADERS = boot
|
||||
|
||||
#
|
||||
# Select the device drivers and filesystems you want
|
||||
#
|
||||
DEVICE_DRIVERS = blue ide keyboard null parallel serial
|
||||
# DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1
|
||||
FS_DRIVERS = vfat
|
||||
# FS_DRIVERS = minix ext2 template
|
||||
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
|
||||
|
||||
APPS = args hello shell test cat bench apc shm lpc thread event
|
||||
|
||||
all: buildno $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS)
|
||||
|
||||
.PHONY: all
|
||||
|
||||
clean: buildno_clean $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_clean) \
|
||||
$(KERNEL_SERVICES:%=%_clean) $(SUBSYS:%=%_clean) $(APPS:%=%_clean)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
floppy: make_floppy_dirs autoexec_floppy $(COMPONENTS:%=%_floppy) \
|
||||
$(DLLS:%=%_floppy) $(LOADERS:%=%_floppy) \
|
||||
$(KERNEL_SERVICES:%=%_floppy) $(SUBSYS:%=%_floppy) \
|
||||
$(APPS:%=%_floppy)
|
||||
|
||||
dist: clean_dist_dir make_dist_dirs $(COMPONENTS:%=%_dist) $(DLLS:%=%_dist) \
|
||||
$(LOADERS:%=%_dist) $(KERNEL_SERVICES:%=%_dist) $(SUBSYS:%=%_dist) \
|
||||
$(APPS:%=%_dist)
|
||||
|
||||
#
|
||||
# Build number generator
|
||||
#
|
||||
buildno: include/reactos/version.h
|
||||
make -C apps/buildno
|
||||
|
||||
buildno_clean:
|
||||
make -C apps/buildno clean
|
||||
|
||||
buildno_floppy:
|
||||
|
||||
buildno_dist:
|
||||
|
||||
.PHONY: buildno buildno_clean buildno_floppy buildno_dist
|
||||
|
||||
#
|
||||
# Applications
|
||||
#
|
||||
$(APPS): %:
|
||||
make -C apps/$*
|
||||
|
||||
$(APPS:%=%_clean): %_clean:
|
||||
make -C apps/$* clean
|
||||
|
||||
$(APPS:%=%_floppy): %_floppy:
|
||||
make -C apps/$* floppy
|
||||
|
||||
$(APPS:%=%_dist): %_dist:
|
||||
make -C apps/$* dist
|
||||
|
||||
.PHONY: $(APPS) $(APPS:%=%_clean) $(APPS:%=%_floppy) $(APPS:%=%_dist)
|
||||
|
||||
#
|
||||
# Interfaces
|
||||
#
|
||||
iface_native:
|
||||
make -C iface/native
|
||||
|
||||
iface_native_clean:
|
||||
make -C iface/native clean
|
||||
|
||||
iface_native_floppy:
|
||||
|
||||
iface_native_dist:
|
||||
|
||||
.PHONY: iface_native iface_native_clean iface_native_floppy \
|
||||
iface_native_dist
|
||||
|
||||
#
|
||||
# Device driver rules
|
||||
#
|
||||
$(DEVICE_DRIVERS): %:
|
||||
make -C services/dd/$*
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_clean): %_clean:
|
||||
make -C services/dd/$* clean
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_floppy): %_floppy:
|
||||
make -C services/dd/$* floppy
|
||||
|
||||
$(DEVICE_DRIVERS:%=%_dist): %_dist:
|
||||
make -C services/dd/$* dist
|
||||
|
||||
.PHONY: $(DEVICE_DRIVERS) $(DEVICE_DRIVERS:%=%_clean) \
|
||||
$(DEVICE_DRIVERS:%=%_floppy) $(DEVICE_DRIVERS:%=%_dist)
|
||||
|
||||
$(FS_DRIVERS): %:
|
||||
make -C services/fs/$*
|
||||
|
||||
$(FS_DRIVERS:%=%_clean): %_clean:
|
||||
make -C services/fs/$* clean
|
||||
|
||||
$(FS_DRIVERS:%=%_floppy): %_floppy:
|
||||
make -C services/fs/$* floppy
|
||||
|
||||
$(FS_DRIVERS:%=%_dist): %_dist:
|
||||
make -C services/fs/$* dist
|
||||
|
||||
.PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_clean) $(FS_DRIVERS:%=%_floppy) \
|
||||
$(FS_DRIVERS:%=%_dist)
|
||||
|
||||
#
|
||||
# Kernel loaders
|
||||
#
|
||||
|
||||
$(LOADERS): %:
|
||||
make -C loaders/$*
|
||||
|
||||
$(LOADERS:%=%_clean): %_clean:
|
||||
make -C loaders/$* clean
|
||||
|
||||
$(LOADERS:%=%_floppy): %_floppy:
|
||||
make -C loaders/$* floppy
|
||||
|
||||
$(LOADERS:%=%_dist): %_dist:
|
||||
make -C loaders/$* dist
|
||||
|
||||
.PHONY: $(LOADERS) $(LOADERS:%=%_clean) $(LOADERS:%=%_floppy) \
|
||||
$(LOADERS:%=%_dist)
|
||||
|
||||
#
|
||||
# Required system components
|
||||
#
|
||||
|
||||
ntoskrnl:
|
||||
make -C ntoskrnl
|
||||
|
||||
ntoskrnl_clean:
|
||||
make -C ntoskrnl clean
|
||||
|
||||
ntoskrnl_floppy:
|
||||
make -C ntoskrnl floppy
|
||||
|
||||
ntoskrnl_dist:
|
||||
make -C ntoskrnl dist
|
||||
|
||||
.PHONY: ntoskrnl ntoskrnl_clean ntoskrnl_floppy ntoskrnl_dist
|
||||
|
||||
#
|
||||
# Required DLLs
|
||||
#
|
||||
|
||||
$(DLLS): %:
|
||||
make -C lib/$*
|
||||
|
||||
$(DLLS:%=%_clean): %_clean:
|
||||
make -C lib/$* clean
|
||||
|
||||
$(DLLS:%=%_floppy): %_floppy:
|
||||
make -C lib/$* floppy
|
||||
|
||||
$(DLLS:%=%_dist): %_dist:
|
||||
make -C lib/$* dist
|
||||
|
||||
.PHONY: $(DLLS) $(DLLS:%=%_clean) $(DLLS:%=%_floppy) $(DLLS:%=%_dist)
|
||||
|
||||
#
|
||||
# Kernel Subsystems
|
||||
#
|
||||
$(SUBSYS): %:
|
||||
make -C subsys/$*
|
||||
|
||||
$(SUBSYS:%=%_clean): %_clean:
|
||||
make -C subsys/$* clean
|
||||
|
||||
$(SUBSYS:%=%_floppy): %_floppy:
|
||||
make -C subsys/$* floppy
|
||||
|
||||
$(SUBSYS:%=%_dist): %_dist:
|
||||
make -C subsys/$* dist
|
||||
|
||||
.PHONY: $(SUBSYS) $(SUBSYS:%=%_clean) $(SUBSYS:%=%_floppy) \
|
||||
$(SUBSYS:%=%_dist)
|
||||
|
||||
#
|
||||
# Make an install floppy
|
||||
#
|
||||
|
||||
install: all
|
||||
./install.sh /mnt/hda1
|
||||
|
||||
make_floppy_dirs:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
mkdir $(FLOPPY_DIR)\dlls
|
||||
mkdir $(FLOPPY_DIR)\apps
|
||||
mkdir $(FLOPPY_DIR)\drivers
|
||||
mkdir $(FLOPPY_DIR)\subsys
|
||||
else
|
||||
mkdir $(FLOPPY_DIR)/dlls $(FLOPPY_DIR)/apps $(FLOPPY_DIR)/drivers
|
||||
mkdir $(FLOPPY_DIR)/subsys
|
||||
endif
|
||||
|
||||
.PHONY: make_floppy_dirs
|
||||
|
||||
autoexec_floppy: $(FLOPPY_DIR)/autoexec.bat
|
||||
|
||||
$(FLOPPY_DIR)/autoexec.bat: bootflop.bat
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) bootflop.bat $(FLOPPY_DIR)\autoexec.bat
|
||||
else
|
||||
$(CP) bootflop.bat $(FLOPPY_DIR)/autoexec.bat
|
||||
endif
|
||||
|
||||
#
|
||||
# Make a distribution saveset
|
||||
#
|
||||
|
||||
clean_dist_dir:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
- $(RM) $(DIST_DIR)\dlls\*.dll
|
||||
- $(RM) $(DIST_DIR)\apps\*.exe
|
||||
- $(RM) $(DIST_DIR)\drivers\*.sys
|
||||
- $(RM) $(DIST_DIR)\subsys\*.exe
|
||||
- $(RMDIR) $(DIST_DIR)\dlls
|
||||
- $(RMDIR) $(DIST_DIR)\apps
|
||||
- $(RMDIR) $(DIST_DIR)\drivers
|
||||
- $(RMDIR) $(DIST_DIR)\subsys
|
||||
- $(RMDIR) $(DIST_DIR)
|
||||
else
|
||||
$(RM) -r $(DIST_DIR)
|
||||
endif
|
||||
|
||||
make_dist_dirs:
|
||||
ifeq ($(DOSCLI),yes)
|
||||
mkdir $(DIST_DIR)
|
||||
mkdir $(DIST_DIR)\dlls
|
||||
mkdir $(DIST_DIR)\apps
|
||||
mkdir $(DIST_DIR)\drivers
|
||||
mkdir $(DIST_DIR)\dlls
|
||||
mkdir $(DIST_DIR)\subsys
|
||||
else
|
||||
mkdir $(DIST_DIR) $(DIST_DIR)/dlls $(DIST_DIR)/apps $(DIST_DIR)/drivers
|
||||
mkdir $(DIST_DIR)/subsys
|
||||
endif
|
||||
|
||||
.PHONY: clean_dist_dir make_dist_dirs
|
||||
|
15
reactos/NEWS
Normal file
15
reactos/NEWS
Normal file
@@ -0,0 +1,15 @@
|
||||
0.0.14: Converted to PE format
|
||||
All system libraries are now dlls
|
||||
|
||||
0.0.13: Mostly bugfixes (I think)
|
||||
|
||||
0.0.12: Added support for multiple processes (not really tested)
|
||||
System calls
|
||||
kernel32 now compiles (only as a static library)
|
||||
Fixed invalid tss bug (hopefully)
|
||||
Added section support
|
||||
Added some of the ZwxxxVirtual calls
|
||||
Added prototype caching functions (only the Minix fsd actually
|
||||
uses them)
|
||||
Added handle access and type checking
|
||||
Prototype APC implementation (no support for user APCs)
|
24
reactos/README
Normal file
24
reactos/README
Normal file
@@ -0,0 +1,24 @@
|
||||
About Reactos
|
||||
|
||||
1. What is Reactos
|
||||
|
||||
A project aiming to make an approximate clone of Windows NT, compatible
|
||||
with most Windows applications.
|
||||
|
||||
The project has a website at http://www.reactos.com/
|
||||
|
||||
2. Building Reactos
|
||||
|
||||
See the INSTALL file for more details.
|
||||
|
||||
3. More information
|
||||
|
||||
See the doc subdirectory for some sparse notes
|
||||
|
||||
4. Who is responsible
|
||||
|
||||
See the CREDITS file
|
||||
|
||||
5. Recent developments
|
||||
|
||||
See the NEWS file
|
33
reactos/apps/common/crt0.c
Normal file
33
reactos/apps/common/crt0.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <windows.h>
|
||||
|
||||
extern int main(int args, char* argv[], char* environ[]);
|
||||
|
||||
static unsigned int _argc = 0;
|
||||
static char** _argv = NULL;
|
||||
static char** _environ = NULL;
|
||||
|
||||
int mainCRTStartup(PWSTR args)
|
||||
{
|
||||
int nRet;
|
||||
|
||||
// SetUnhandledExceptionFilter(NULL);
|
||||
|
||||
// _fpreset();
|
||||
|
||||
// __GetMainArgs(&_argc, &_argv, &_environ, 0);
|
||||
|
||||
nRet = main(_argc, _argv, _environ);
|
||||
|
||||
// _cexit();
|
||||
|
||||
ExitProcess(nRet);
|
||||
}
|
||||
|
||||
int WinMainCRTStartup()
|
||||
{
|
||||
return mainCRTStartup(NULL);
|
||||
}
|
||||
|
||||
void __main(void)
|
||||
{
|
||||
}
|
97
reactos/apps/tests/apc/apc.c
Normal file
97
reactos/apps/tests/apc/apc.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
VOID STDCALL ApcRoutine(PVOID Context,
|
||||
PIO_STATUS_BLOCK IoStatus,
|
||||
ULONG Reserved)
|
||||
{
|
||||
printf("(apc.exe) ApcRoutine(Context %x)\n", Context);
|
||||
}
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING FileName;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
CHAR Buffer[256];
|
||||
HANDLE EventHandle;
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
printf("APC test program\n");
|
||||
|
||||
EventHandle = CreateEventW(NULL,
|
||||
FALSE,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (EventHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Failed to create event\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Opening file\n");
|
||||
RtlInitUnicodeString(&FileName,
|
||||
L"\\C:\\a.txt");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&FileName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
printf("Creating file\n");
|
||||
FileHandle = CreateFileW(L"C:\\a.txt",
|
||||
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("Open failed\n");
|
||||
return;
|
||||
}
|
||||
printf("Reading file\n");
|
||||
Status = ZwReadFile(FileHandle,
|
||||
NULL,
|
||||
ApcRoutine,
|
||||
0xdeadbeef,
|
||||
&IoStatus,
|
||||
Buffer,
|
||||
256,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("Read failed\n");
|
||||
}
|
||||
printf("Waiting\n");
|
||||
WaitForSingleObjectEx(EventHandle, INFINITE, TRUE);
|
||||
printf("Returned from wait\n");
|
||||
ZwClose(FileHandle);
|
||||
printf("Program finished\n");
|
||||
for(;;);
|
||||
}
|
||||
|
44
reactos/apps/tests/apc/makefile
Normal file
44
reactos/apps/tests/apc/makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= ../common/crt0.o apc.o
|
||||
PROGS= apc.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) apc.o
|
||||
- $(RM) apc.exe
|
||||
- $(RM) apc.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
apc.exe: $(OBJECTS) $(LIBS)
|
||||
$(LD) $(OBJECTS) $(LIBS) -o apc.exe
|
||||
$(NM) --numeric-sort apc.exe > apc.sym
|
||||
|
||||
include ../../rules.mak
|
39
reactos/apps/tests/args/args.c
Normal file
39
reactos/apps/tests/args/args.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
debug_printf("GetCommandLineA() %s\n",GetCommandLineA());
|
||||
debug_printf("argc %d\n", argc);
|
||||
for (i=0; i<argc; i++)
|
||||
{
|
||||
debug_printf("Argv[%d]: %x\n",i,argv[i]);
|
||||
debug_printf("Argv[%d]: '%s'\n",i,argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
42
reactos/apps/tests/args/makefile
Normal file
42
reactos/apps/tests/args/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= args.o
|
||||
PROGS= args.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) args.o
|
||||
- $(RM) args.exe
|
||||
- $(RM) args.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
args.exe: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o args.exe
|
||||
$(NM) --numeric-sort args.exe > args.sym
|
||||
|
||||
include ../../rules.mak
|
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
8
reactos/apps/tests/bench/bench-syscall.c
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
}
|
82
reactos/apps/tests/bench/bench-thread.c
Normal file
82
reactos/apps/tests/bench/bench-thread.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NR_THREADS (0x1)
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
thread_main1(LPVOID param)
|
||||
{
|
||||
printf("Thread 1 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI
|
||||
thread_main2(LPVOID param)
|
||||
{
|
||||
printf("Thread 2 running (Counter %lu)\n", (DWORD)param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD i=0;
|
||||
DWORD id;
|
||||
|
||||
#if 1
|
||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
/* CreateThread(NULL,
|
||||
0,
|
||||
thread_main2,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);*/
|
||||
}
|
||||
|
||||
printf("All threads created...\n");
|
||||
|
||||
/*
|
||||
* Waiting for threads is not implemented yet.
|
||||
* If you want to see all threads running, uncomment the
|
||||
* call to SuspendThread(). The test application will
|
||||
* freeze after all threads are created.
|
||||
*/
|
||||
/* SuspendThread (GetCurrentThread()); */
|
||||
|
||||
#else
|
||||
|
||||
printf("Creating thread...\n");
|
||||
|
||||
hThread = CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
printf("Thread created. Waiting for termination...\n");
|
||||
|
||||
WaitForSingleObject (hThread,
|
||||
-1);
|
||||
|
||||
CloseHandle (hThread);
|
||||
|
||||
printf("Thread terminated...\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
41
reactos/apps/tests/bench/makefile
Normal file
41
reactos/apps/tests/bench/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = bench-thread
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
bench-thread.exe: bench-thread.c
|
||||
$(CC) $(CFLAGS) bench-thread.c -lkernel32 -o bench-thread.exe
|
||||
$(NM) --numeric-sort bench-thread.exe > bench-thread.sym
|
||||
|
||||
include ../../rules.mak
|
33
reactos/apps/tests/event/event.c
Normal file
33
reactos/apps/tests/event/event.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE events[2];
|
||||
|
||||
DWORD WINAPI thread( LPVOID crap )
|
||||
{
|
||||
SetEvent( events[0] );
|
||||
if( crap )
|
||||
SetEvent( events[1] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
DWORD id, Status;
|
||||
printf( "Creating events\n" );
|
||||
events[0] = CreateEvent( 0, TRUE, FALSE, 0 );
|
||||
events[1] = CreateEvent( 0, TRUE, FALSE, 0 );
|
||||
printf( "Created events\n" );
|
||||
CreateThread( 0, 0, thread, 0, 0, &id );
|
||||
printf( "WaitForSingleObject %s\n", ( WaitForSingleObject( events[0], INFINITE ) == WAIT_OBJECT_0 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
CreateThread( 0, 0, thread, 0, 0, &id );
|
||||
printf( "WaitForMultipleObjects with waitall = FALSE %s\n", ( WaitForMultipleObjects( 2, events, FALSE, INFINITE ) == WAIT_OBJECT_0 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
CreateThread( 0, 0, thread, (void *)1, 0, &id );
|
||||
Status = WaitForMultipleObjects( 2, events, TRUE, INFINITE );
|
||||
printf( "WaitForMultipleObjects with waitall = TRUE %s\n", ( Status == WAIT_OBJECT_0 || Status == WAIT_OBJECT_0 + 1 ? "worked" : "failed" ) );
|
||||
ResetEvent( events[0] );
|
||||
printf( "WaitForSingleObject with timeout %s\n", ( WaitForSingleObject( events[0], 100 ) == WAIT_TIMEOUT ? "worked" : "failed" ) );
|
||||
return 0;
|
||||
}
|
41
reactos/apps/tests/event/makefile
Normal file
41
reactos/apps/tests/event/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = event
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
event.exe: event.c
|
||||
$(CC) $(CFLAGS) event.c -lkernel32 -o event.exe
|
||||
$(NM) --numeric-sort event.exe > event.sym
|
||||
|
||||
include ../../rules.mak
|
8
reactos/apps/tests/hello/hello.c
Normal file
8
reactos/apps/tests/hello/hello.c
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
printf("Hello world\n");
|
||||
return(0);
|
||||
}
|
39
reactos/apps/tests/hello/makefile
Normal file
39
reactos/apps/tests/hello/makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS = hello.o
|
||||
PROGS = hello.exe
|
||||
LIBS =
|
||||
CLEAN_FILES = hello.o hello.exe
|
||||
|
||||
all: hello.exe
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
hello.exe: $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o hello.exe
|
||||
|
||||
include ../../rules.mak
|
205
reactos/apps/tests/lpc/conport.c
Normal file
205
reactos/apps/tests/lpc/conport.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/* $Id: conport.c,v 1.5 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/conport.c
|
||||
*
|
||||
* To be run in a real WNT 4.0 system with
|
||||
* "\SmApiPort" as argument. Do not try to
|
||||
* connect to "\Windows\ApiPort" since that
|
||||
* reboots immeditely.
|
||||
*
|
||||
* Use Russinovich' HandleEx to verify
|
||||
* conport.exe owns two unnamed LPC ports:
|
||||
* the one created by kernel32.dll connecting
|
||||
* to csrss.exe, and one connected to here.
|
||||
*
|
||||
* 19990627 (Emanuele Aliberti)
|
||||
* Initial implementation.
|
||||
* 19990704 (EA)
|
||||
* Dump object's attributes moved in dumpinfo.c.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define PROTO_LPC
|
||||
#include <ddk/ntddk.h>
|
||||
#include "dumpinfo.h"
|
||||
|
||||
#define LPC_CONNECT_FLAG1 0x00000001
|
||||
#define LPC_CONNECT_FLAG2 0x00000010
|
||||
#define LPC_CONNECT_FLAG3 0x00000100
|
||||
#define LPC_CONNECT_FLAG4 0x00001000
|
||||
#define LPC_CONNECT_FLAG5 0x00010000
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * ConnectPort)(
|
||||
OUT PHANDLE PortHandle,
|
||||
IN PUNICODE_STRING PortName,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN DWORD Unknown3,
|
||||
IN DWORD Unknown4,
|
||||
IN DWORD Unknown5,
|
||||
IN DWORD Unknown6,
|
||||
IN ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * YieldExecution)(VOID);
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAXARG 1000000
|
||||
|
||||
|
||||
VOID
|
||||
TryConnectPort(char *port_name)
|
||||
{
|
||||
DWORD Status = 0;
|
||||
HANDLE Port = 0;
|
||||
int i;
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
WORD Name [BUF_SIZE] = {0};
|
||||
int dwx = 0;
|
||||
char * port_name_save = port_name;
|
||||
|
||||
/*
|
||||
* Convert the port's name to Unicode.
|
||||
*/
|
||||
for (
|
||||
PortName.Length = 0;
|
||||
( *port_name
|
||||
&& (PortName.Length < BUF_SIZE)
|
||||
);
|
||||
)
|
||||
{
|
||||
Name[PortName.Length++] = (WORD) *port_name++;
|
||||
}
|
||||
Name[PortName.Length] = 0;
|
||||
|
||||
PortName.Length = PortName.Length * sizeof (WORD);
|
||||
PortName.MaximumLength = PortName.Length + sizeof (WORD);
|
||||
PortName.Buffer = (PWSTR) Name;
|
||||
/*
|
||||
* Prepare the port object attributes.
|
||||
*/
|
||||
ObjectAttributes.Length =
|
||||
sizeof (OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory =
|
||||
NULL;
|
||||
ObjectAttributes.ObjectName =
|
||||
NULL /*& PortName */;
|
||||
ObjectAttributes.Attributes =
|
||||
OBJ_CASE_INSENSITIVE;
|
||||
ObjectAttributes.SecurityDescriptor =
|
||||
NULL;
|
||||
ObjectAttributes.SecurityQualityOfService =
|
||||
NULL;
|
||||
/*
|
||||
* Try to issue a connection request.
|
||||
*/
|
||||
Port = 0;
|
||||
Status = ConnectPort(
|
||||
& Port,
|
||||
& PortName,
|
||||
& ObjectAttributes,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
LPC_CONNECT_FLAG5
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DumpInfo(
|
||||
Name,
|
||||
Status,
|
||||
"connected",
|
||||
Port
|
||||
);
|
||||
/* Hot waiting */
|
||||
for (dwx=0; dwx<MAXARG; ++dwx)
|
||||
{
|
||||
YieldExecution();
|
||||
}
|
||||
if (FALSE == CloseHandle(Port))
|
||||
{
|
||||
printf(
|
||||
"Could not close the port handle %08X.\n",
|
||||
Port
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf(
|
||||
"Connection to port \"%s\" failed (Status = %08X).\n",
|
||||
port_name_save,
|
||||
Status
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
main( int argc, char * argv[] )
|
||||
{
|
||||
HINSTANCE ntdll;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("WNT LPC Port Connector\n");
|
||||
printf("Usage: %s [port_name]\n",argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("LoadLibrary(NTDLL)\n");
|
||||
ntdll = LoadLibrary("NTDLL");
|
||||
if (ntdll == NULL)
|
||||
{
|
||||
printf("Could not load NTDLL\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtConnectPort)\n");
|
||||
ConnectPort = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtConnectPort"
|
||||
);
|
||||
if (ConnectPort == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtConnectPort\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtQueryObject)\n");
|
||||
QueryObject = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtQueryObject"
|
||||
);
|
||||
if (QueryObject == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtQueryObject\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtYieldExecution)\n");
|
||||
YieldExecution = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtYieldExecution"
|
||||
);
|
||||
if (YieldExecution == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtYieldExecution\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("TryConnectPort(%s)\n",argv[1]);
|
||||
TryConnectPort(argv[1]);
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
192
reactos/apps/tests/lpc/creport.c
Normal file
192
reactos/apps/tests/lpc/creport.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/* $Id: creport.c,v 1.2 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/creport.c
|
||||
*
|
||||
* To be run in a real WNT 4.0 system to
|
||||
* create an LPC named port.
|
||||
*
|
||||
* Use Russinovich' HandleEx to verify
|
||||
* creport.exe owns the named LPC port
|
||||
* you asked to create.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define PROTO_LPC
|
||||
#include <ddk/ntddk.h>
|
||||
#include "dumpinfo.h"
|
||||
|
||||
#define LPC_CONNECT_FLAG1 0x00000001
|
||||
#define LPC_CONNECT_FLAG2 0x00000010
|
||||
#define LPC_CONNECT_FLAG3 0x00000100
|
||||
#define LPC_CONNECT_FLAG4 0x00001000
|
||||
#define LPC_CONNECT_FLAG5 0x00010000
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * CreatePort)(
|
||||
/*OUT PHANDLE PortHandle,*/
|
||||
PVOID Buffer,
|
||||
IN POBJECT_ATTRIBUTES PortAttributes OPTIONAL,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN DWORD Unknown3,
|
||||
IN ULONG Flags
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
(STDCALL * YieldExecution)(VOID);
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAXARG 5000000
|
||||
|
||||
|
||||
VOID
|
||||
TryCreatePort(char *port_name)
|
||||
{
|
||||
DWORD Status = 0;
|
||||
HANDLE Port = 0;
|
||||
int i;
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
WORD Name [BUF_SIZE] = {0};
|
||||
int dwx = 0;
|
||||
char * port_name_save = port_name;
|
||||
|
||||
/*
|
||||
* Convert the port's name to Unicode.
|
||||
*/
|
||||
for (
|
||||
PortName.Length = 0;
|
||||
( *port_name
|
||||
&& (PortName.Length < BUF_SIZE)
|
||||
);
|
||||
)
|
||||
{
|
||||
Name[PortName.Length++] = (WORD) *port_name++;
|
||||
}
|
||||
Name[PortName.Length] = 0;
|
||||
|
||||
PortName.Length = PortName.Length * sizeof (WORD);
|
||||
PortName.MaximumLength = PortName.Length + sizeof (WORD);
|
||||
PortName.Buffer = (PWSTR) Name;
|
||||
/*
|
||||
* Prepare the port object attributes.
|
||||
*/
|
||||
ObjectAttributes.Length =
|
||||
sizeof (OBJECT_ATTRIBUTES);
|
||||
ObjectAttributes.RootDirectory =
|
||||
NULL;
|
||||
ObjectAttributes.ObjectName =
|
||||
& PortName;
|
||||
ObjectAttributes.Attributes =
|
||||
0; //OBJ_CASE_INSENSITIVE --> STATUS_INVALID_PARAMETER ==> case sensitive!;
|
||||
ObjectAttributes.SecurityDescriptor =
|
||||
NULL;
|
||||
ObjectAttributes.SecurityQualityOfService =
|
||||
NULL;
|
||||
/*
|
||||
* Try to issue a connection request.
|
||||
*/
|
||||
Port = 0;
|
||||
Status = CreatePort(
|
||||
& Port,
|
||||
& ObjectAttributes,
|
||||
0, /* ACCESS_MASK? */
|
||||
0, /* Unknown3 */
|
||||
LPC_CONNECT_FLAG5
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DumpInfo(
|
||||
Name,
|
||||
Status,
|
||||
"created",
|
||||
Port
|
||||
);
|
||||
/* Hot waiting */
|
||||
for (dwx=0; dwx<MAXARG; ++dwx)
|
||||
{
|
||||
YieldExecution();
|
||||
}
|
||||
if (FALSE == CloseHandle(Port))
|
||||
{
|
||||
printf(
|
||||
"Could not close the port handle %08X.\n",
|
||||
Port
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf(
|
||||
"Creating port \"%s\" failed (Status = %08X).\n",
|
||||
port_name_save,
|
||||
Status
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
main( int argc, char * argv[] )
|
||||
{
|
||||
HINSTANCE ntdll;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf("WNT LPC Port Creator\n");
|
||||
printf("Usage: %s [port_name]\n",argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("LoadLibrary(NTDLL)\n");
|
||||
ntdll = LoadLibrary("NTDLL");
|
||||
if (ntdll == NULL)
|
||||
{
|
||||
printf("Could not load NTDLL\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtCreatePort)\n");
|
||||
CreatePort = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtCreatePort"
|
||||
);
|
||||
if (CreatePort == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtCreatePort\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtQueryObject)\n");
|
||||
QueryObject = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtQueryObject"
|
||||
);
|
||||
if (QueryObject == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtQueryObject\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GetProcAddress(NTDLL.NtYieldExecution)\n");
|
||||
YieldExecution = (VOID*) GetProcAddress(
|
||||
ntdll,
|
||||
"NtYieldExecution"
|
||||
);
|
||||
if (YieldExecution == NULL)
|
||||
{
|
||||
FreeLibrary(ntdll);
|
||||
printf("Could not find NTDLL.NtYieldExecution\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("TryCreatePort(%s)\n",argv[1]);
|
||||
TryCreatePort(argv[1]);
|
||||
printf("Done\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
239
reactos/apps/tests/lpc/dumpinfo.c
Normal file
239
reactos/apps/tests/lpc/dumpinfo.c
Normal file
@@ -0,0 +1,239 @@
|
||||
/* $Id: dumpinfo.c,v 1.2 1999/07/17 23:10:12 ea Exp $
|
||||
*
|
||||
* reactos/apps/lpc/dumpinfo.c
|
||||
*
|
||||
* ReactOS Operating System
|
||||
*
|
||||
* Dump a kernel object's attributes by its handle.
|
||||
*
|
||||
* 19990627 (Emanuele Aliberti)
|
||||
* Initial implementation.
|
||||
* 19990704 (EA)
|
||||
* Added code to find the basic information buffer size
|
||||
* for the LPC port object.
|
||||
* 19990710 (EA)
|
||||
*
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
#define MAX_BASIC_INFO_SIZE 512
|
||||
|
||||
|
||||
extern
|
||||
NTSTATUS
|
||||
(STDCALL * QueryObject)(
|
||||
IN HANDLE ObjectHandle,
|
||||
IN CINT ObjectInformationClass,
|
||||
OUT PVOID ObjectInformation,
|
||||
IN ULONG Length,
|
||||
OUT PULONG ResultLength
|
||||
);
|
||||
|
||||
extern
|
||||
NTSTATUS
|
||||
(STDCALL * QueryInformationPort)(
|
||||
IN HANDLE PortHandle,
|
||||
IN CINT PortInformationClass, /* guess */
|
||||
OUT PVOID PortInformation, /* guess */
|
||||
IN ULONG PortInformationLength, /* guess */
|
||||
OUT PULONG ReturnLength /* guess */
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
static
|
||||
VOID
|
||||
DumpBuffer(
|
||||
char *Name,
|
||||
BYTE *buffer,
|
||||
ULONG size
|
||||
)
|
||||
{
|
||||
register ULONG i = 0;
|
||||
|
||||
printf("%s [%d] = ",Name,size);
|
||||
for ( i = 0;
|
||||
i != size;
|
||||
++i
|
||||
)
|
||||
{
|
||||
printf("%02X",buffer[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
*/
|
||||
|
||||
VOID
|
||||
DumpInfo (
|
||||
LPCWSTR Name,
|
||||
NTSTATUS Status,
|
||||
LPCWSTR Comment,
|
||||
HANDLE Port
|
||||
)
|
||||
{
|
||||
BYTE ObjectInformation [BUF_SIZE] = {0};
|
||||
ULONG ResultLength;
|
||||
|
||||
wprintf(
|
||||
L"Port \"%s\" %s:\n",
|
||||
Name,
|
||||
Comment
|
||||
);
|
||||
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
printf("\tPort = %08X\n\n",Port);
|
||||
/*
|
||||
* Query object information.
|
||||
*/
|
||||
printf("Basic Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectBasicInformation,
|
||||
ObjectInformation,
|
||||
sizeof (LPC_PORT_BASIC_INFORMATION),
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
PLPC_PORT_BASIC_INFORMATION i;
|
||||
|
||||
i = (PLPC_PORT_BASIC_INFORMATION) ObjectInformation;
|
||||
|
||||
printf( "\tUnknown01 = 0x%08X\n", i->Unknown0 );
|
||||
printf( "\tUnknown02 = 0x%08X\n", i->Unknown1 );
|
||||
printf( "\tUnknown03 = 0x%08X\n", i->Unknown2 );
|
||||
printf( "\tUnknown04 = 0x%08X\n", i->Unknown3 );
|
||||
printf( "\tUnknown05 = 0x%08X\n", i->Unknown4 );
|
||||
printf( "\tUnknown06 = 0x%08X\n", i->Unknown5 );
|
||||
printf( "\tUnknown07 = 0x%08X\n", i->Unknown6 );
|
||||
printf( "\tUnknown08 = 0x%08X\n", i->Unknown7 );
|
||||
printf( "\tUnknown09 = 0x%08X\n", i->Unknown8 );
|
||||
printf( "\tUnknown10 = 0x%08X\n", i->Unknown9 );
|
||||
printf( "\tUnknown11 = 0x%08X\n", i->Unknown10 );
|
||||
printf( "\tUnknown12 = 0x%08X\n", i->Unknown11 );
|
||||
printf( "\tUnknown13 = 0x%08X\n", i->Unknown12 );
|
||||
printf( "\tUnknown14 = 0x%08X\n", i->Unknown13 );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Type Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectTypeInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_TYPE_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_TYPE_INFORMATION *) ObjectInformation;
|
||||
|
||||
wprintf(
|
||||
L"\tName: \"%s\"\n",
|
||||
(i->Name.Length ? i->Name.Buffer : L"")
|
||||
);
|
||||
/*
|
||||
FIXME: why this always raise an access violation exception?
|
||||
wprintf(
|
||||
L"\tType: \"%s\"\n",
|
||||
(i->Type.Length ? i->Type.Buffer : L"")
|
||||
);
|
||||
/**/
|
||||
printf(
|
||||
"\tTotal Handles: %d\n",
|
||||
i->TotalHandles
|
||||
);
|
||||
printf(
|
||||
"\tReference Count: %d\n",
|
||||
i->ReferenceCount
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Name Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectNameInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_NAME_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_NAME_INFORMATION *) ObjectInformation;
|
||||
wprintf(
|
||||
L"\tName: \"%s\"\n",
|
||||
(i->Name.Length ? i->Name.Buffer : L"")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
printf("Data Information:\n");
|
||||
Status = QueryObject(
|
||||
Port,
|
||||
ObjectDataInformation,
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
OBJECT_DATA_INFORMATION * i;
|
||||
|
||||
i = (OBJECT_DATA_INFORMATION *) ObjectInformation;
|
||||
printf(
|
||||
"\tInherit Handle: %s\n",
|
||||
(i->bInheritHandle ? "TRUE" : "FALSE")
|
||||
);
|
||||
printf(
|
||||
"\tProtect from Close: %s\n",
|
||||
(i->bProtectFromClose ? "TRUE" : "FALSE")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
//---
|
||||
printf("Port Information:\n");
|
||||
/* Status = QueryInformationPort(
|
||||
Port,
|
||||
1, /* info class * /
|
||||
ObjectInformation,
|
||||
sizeof ObjectInformation,
|
||||
& ResultLength
|
||||
);
|
||||
if (Status == STATUS_SUCCESS)
|
||||
{
|
||||
DWORD * i = ObjectInformation;
|
||||
int j = 0;
|
||||
|
||||
while (j < ResultLength / sizeof (DWORD))
|
||||
{
|
||||
printf("\t%08X\n",i[j]);
|
||||
++j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\tStatus = %08X\n",Status);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
8
reactos/apps/tests/lpc/dumpinfo.h
Normal file
8
reactos/apps/tests/lpc/dumpinfo.h
Normal file
@@ -0,0 +1,8 @@
|
||||
VOID
|
||||
DumpInfo (
|
||||
LPCWSTR Name,
|
||||
NTSTATUS Status,
|
||||
LPCWSTR Comment,
|
||||
HANDLE Port
|
||||
);
|
||||
|
62
reactos/apps/tests/lpc/lpcclt.c
Normal file
62
reactos/apps/tests/lpc/lpcclt.c
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
UNICODE_STRING PortName;
|
||||
NTSTATUS Status;
|
||||
HANDLE PortHandle;
|
||||
LPCMESSAGE Request;
|
||||
ULONG ConnectInfoLength;
|
||||
|
||||
printf("(lpcclt.exe) Lpc client\n");
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\TestPort");
|
||||
|
||||
printf("(lpcclt.exe) Connecting to port\n");
|
||||
ConnectInfoLength = 0;
|
||||
Status = NtConnectPort(&PortHandle,
|
||||
&PortName,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&ConnectInfoLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcclt.exe) Failed to connect\n");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(Request.MessageData, GetCommandLineA());
|
||||
Request.ActualMessageLength = strlen(Request.MessageData);
|
||||
Request.TotalMessageLength = sizeof(LPCMESSAGE);
|
||||
|
||||
printf("(lpcclt.exe) Sending message\n");
|
||||
Status = NtRequestPort(PortHandle, &Request);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcclt.exe) Failed to send request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcclt.exe) Succeeded\n");
|
||||
}
|
98
reactos/apps/tests/lpc/lpcsrv.c
Normal file
98
reactos/apps/tests/lpc/lpcsrv.c
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char* argv[])
|
||||
{
|
||||
UNICODE_STRING PortName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS Status;
|
||||
HANDLE NamedPortHandle;
|
||||
HANDLE PortHandle;
|
||||
LPCMESSAGE ConnectMsg;
|
||||
|
||||
printf("(lpcsrv.exe) Lpc test server\n");
|
||||
|
||||
RtlInitUnicodeString(&PortName, L"\\TestPort");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&PortName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
printf("(lpcsrv.exe) Creating port\n");
|
||||
Status = NtCreatePort(&NamedPortHandle,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to create port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
printf("(lpcsrv.exe) Listening for connections\n");
|
||||
Status = NtListenPort(NamedPortHandle,
|
||||
&ConnectMsg);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to listen for connections\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Accepting connections\n");
|
||||
Status = NtAcceptConnectPort(&PortHandle,
|
||||
NamedPortHandle,
|
||||
NULL,
|
||||
1,
|
||||
0,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to accept connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Completing connection\n");
|
||||
Status = NtCompleteConnectPort(PortHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to complete connection\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
LPCMESSAGE Request;
|
||||
|
||||
Status = NtReplyWaitReceivePort(PortHandle,
|
||||
0,
|
||||
NULL,
|
||||
&Request);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
printf("(lpcsrv.exe) Failed to receive request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("(lpcsrv.exe) Message contents are <%s>\n", Request.MessageData);
|
||||
}
|
||||
}
|
51
reactos/apps/tests/lpc/makefile
Normal file
51
reactos/apps/tests/lpc/makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
SRV_OBJECTS= ../common/crt0.o lpcsrv.o
|
||||
CLT_OBJECTS= ../common/crt0.o lpcclt.o
|
||||
|
||||
PROGS= lpcsrv.exe lpcclt.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) lpcsrv.o
|
||||
- $(RM) lpcsrv.exe
|
||||
- $(RM) lpcsrv.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
lpcsrv.exe: $(SRV_OBJECTS) $(LIBS)
|
||||
$(LD) $(SRV_OBJECTS) $(LIBS) -o lpcsrv.exe
|
||||
$(NM) --numeric-sort lpcsrv.exe > lpcsrv.sym
|
||||
|
||||
lpcclt.exe: $(CLT_OBJECTS) $(LIBS)
|
||||
$(LD) $(CLT_OBJECTS) $(LIBS) -o lpcclt.exe
|
||||
$(NM) --numeric-sort lpcclt.exe > lpcclt.sym
|
||||
|
||||
|
||||
include ../../rules.mak
|
51
reactos/apps/tests/shm/makefile
Normal file
51
reactos/apps/tests/shm/makefile
Normal file
@@ -0,0 +1,51 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
SRV_OBJECTS= ../common/crt0.o shmsrv.o
|
||||
CLT_OBJECTS= ../common/crt0.o shmclt.o
|
||||
|
||||
PROGS= shmsrv.exe shmclt.exe
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
|
||||
../../lib/ntdll/ntdll.a
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) *.o
|
||||
- $(RM) *.exe
|
||||
- $(RM) *.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
shmsrv.exe: $(SRV_OBJECTS) $(LIBS)
|
||||
$(LD) $(SRV_OBJECTS) $(LIBS) -o shmsrv.exe
|
||||
$(NM) --numeric-sort shmsrv.exe > shmsrv.sym
|
||||
|
||||
shmclt.exe: $(CLT_OBJECTS) $(LIBS)
|
||||
$(LD) $(CLT_OBJECTS) $(LIBS) -o shmclt.exe
|
||||
$(NM) --numeric-sort shmsrv.exe > shmclt.sym
|
||||
|
||||
|
||||
include ../../rules.mak
|
60
reactos/apps/tests/shm/shmclt.c
Normal file
60
reactos/apps/tests/shm/shmclt.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
HANDLE OutputHandle;
|
||||
HANDLE InputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
HANDLE Section;
|
||||
PVOID BaseAddress;
|
||||
char buffer[256];
|
||||
|
||||
printf("Shm test server\n");
|
||||
|
||||
Section = OpenFileMappingW (
|
||||
// PAGE_EXECUTE_READWRITE, invalid parameter
|
||||
FILE_MAP_WRITE,
|
||||
FALSE,
|
||||
L"TestSection"
|
||||
);
|
||||
if (Section == NULL)
|
||||
{
|
||||
printf("Failed to open section (err=%d)", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
BaseAddress = MapViewOfFile(Section,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
8192);
|
||||
if (BaseAddress == NULL)
|
||||
{
|
||||
printf("Failed to map section (err=%d)\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
printf("BaseAddress %x\n", (UINT) BaseAddress);
|
||||
printf("Copying from section\n");
|
||||
strcpy(buffer, BaseAddress);
|
||||
printf("Copyed <%s>\n", buffer);
|
||||
|
||||
// for(;;);
|
||||
return 0;
|
||||
}
|
||||
|
52
reactos/apps/tests/shm/shmsrv.c
Normal file
52
reactos/apps/tests/shm/shmsrv.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* $Id: shmsrv.c,v 1.3 1999/12/30 01:51:36 dwelch Exp $
|
||||
*
|
||||
* FILE : reactos/apps/shm/shmsrv.c
|
||||
* AUTHOR: David Welch
|
||||
*/
|
||||
#include <ddk/ntddk.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
HANDLE Section;
|
||||
PVOID BaseAddress;
|
||||
|
||||
printf("Shm test server\n");
|
||||
|
||||
Section = CreateFileMappingW (
|
||||
(HANDLE) 0xFFFFFFFF,
|
||||
NULL,
|
||||
PAGE_READWRITE,
|
||||
0,
|
||||
8192,
|
||||
L"TestSection"
|
||||
);
|
||||
if (Section == NULL)
|
||||
{
|
||||
printf("Failed to create section (err=%d)", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Mapping view of section\n");
|
||||
BaseAddress = MapViewOfFile(Section,
|
||||
FILE_MAP_ALL_ACCESS,
|
||||
0,
|
||||
0,
|
||||
8192);
|
||||
printf("BaseAddress %x\n", (UINT) BaseAddress);
|
||||
if (BaseAddress == NULL)
|
||||
{
|
||||
printf("Failed to map section\n");
|
||||
}
|
||||
|
||||
printf("Copying to section\n");
|
||||
printf("Copying %s\n", GetCommandLineA());
|
||||
strcpy(BaseAddress, GetCommandLineA());
|
||||
|
||||
for(;;);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
11
reactos/apps/tests/test_old/bug2.c
Normal file
11
reactos/apps/tests/test_old/bug2.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int i;
|
||||
puts ("This should print \"wow = I\" for I from 0 to 39 inclusive.");
|
||||
for (i = 0; i < 40; i++)
|
||||
printf ("%s = %d\n", "wow", i);
|
||||
return 0;
|
||||
}
|
53
reactos/apps/tests/test_old/bug3.c
Normal file
53
reactos/apps/tests/test_old/bug3.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
const char filename[] = "/tmp/bug3.test";
|
||||
|
||||
f = fopen(filename, "w+");
|
||||
for (i=0; i<9000; i++)
|
||||
putc ('x', f);
|
||||
fseek (f, 8180L, 0);
|
||||
fwrite ("Where does this text go?", 1, 24, f);
|
||||
fflush (f);
|
||||
|
||||
rewind (f);
|
||||
for (i=0; i<9000; i++)
|
||||
{
|
||||
int j;
|
||||
|
||||
if ((j = getc(f)) != 'x')
|
||||
{
|
||||
if (i != 8180)
|
||||
{
|
||||
printf ("Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[25];
|
||||
|
||||
buf[0] = j;
|
||||
fread (buf + 1, 1, 23, f);
|
||||
buf[24] = '\0';
|
||||
if (strcmp (buf, "Where does this text go?") != 0)
|
||||
{
|
||||
printf ("%s\nTest FAILED!\n", buf);
|
||||
return 1;
|
||||
}
|
||||
i += 23;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
remove(filename);
|
||||
|
||||
puts ("Test succeeded.");
|
||||
|
||||
return 0;
|
||||
}
|
74
reactos/apps/tests/test_old/makefile
Normal file
74
reactos/apps/tests/test_old/makefile
Normal file
@@ -0,0 +1,74 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS= test-stdio tst-printf tstdiomisc bug2 bug3 \
|
||||
temptest test-fseek test_rdwr
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
bug2.exe: bug2.c
|
||||
$(CC) bug2.c -lkernel32 -o bug2.exe
|
||||
$(NM) --numeric-sort bug2.exe > bug2.sym
|
||||
|
||||
bug3.exe: bug3.c
|
||||
$(CC) bug3.c -lkernel32 -o bug3.exe
|
||||
$(NM) --numeric-sort bug3.exe > bug3.sym
|
||||
|
||||
temptest.exe: temptest.c
|
||||
$(CC) temptest.c -lkernel32 -o temptest.exe
|
||||
$(NM) --numeric-sort temptest.exe > temptest.sym
|
||||
|
||||
test-fseek.exe: test-fseek.c
|
||||
$(CC) test-fseek.c -lkernel32 -o test-fseek.exe
|
||||
$(NM) --numeric-sort test-fseek.exe > test-fseek.sym
|
||||
|
||||
test-fwrite.exe: test-fwrite.c
|
||||
$(CC) test-fwrite.c -lkernel32 -o test-fwrite.exe
|
||||
$(NM) --numeric-sort test-fwrite.exe > test-fwrite.sym
|
||||
|
||||
test_rdwr.exe: test_rdwr.c
|
||||
$(CC) test_rdwr.c -lkernel32 -o test_rdwr.exe
|
||||
$(NM) --numeric-sort test_rdwr.exe > test_rdwr.sym
|
||||
|
||||
test-stdio.exe: test-stdio.c
|
||||
$(CC) test-stdio.c -lkernel32 -o test-stdio.exe
|
||||
$(NM) --numeric-sort test-stdio.exe > test-stdio.sym
|
||||
|
||||
tst-printf.exe: tst-printf.c
|
||||
$(CC) tst-printf.c -lkernel32 -o tst-printf.exe
|
||||
$(NM) --numeric-sort tst-printf.exe > tst-printf.sym
|
||||
|
||||
tstdiomisc.exe: tstdiomisc.c
|
||||
$(CC) tstdiomisc.c -lkernel32 -o tstdiomisc.exe
|
||||
$(NM) --numeric-sort tstdiomisc.exe > tstdiomisc.sym
|
||||
|
||||
include ../../rules.mak
|
27
reactos/apps/tests/test_old/temptest.c
Normal file
27
reactos/apps/tests/test_old/temptest.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char *files[500];
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 500; i++) {
|
||||
files[i] = tempnam (NULL, "file");
|
||||
if (files[i] == NULL) {
|
||||
printf ("tempnam failed\n");
|
||||
exit (1);
|
||||
}
|
||||
printf ("file: %s\n", files[i]);
|
||||
fp = fopen (files[i], "w");
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
remove (files[i]);
|
||||
|
||||
exit (0);
|
||||
}
|
85
reactos/apps/tests/test_old/test-fseek.c
Normal file
85
reactos/apps/tests/test_old/test-fseek.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TESTFILE "/tmp/test.dat"
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
FILE *fp;
|
||||
int i, j;
|
||||
|
||||
puts ("\nFile seek test");
|
||||
fp = fopen (TESTFILE, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
perror (TESTFILE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
putc (i, fp);
|
||||
if (freopen (TESTFILE, "r", fp) != fp)
|
||||
{
|
||||
perror ("Cannot open file for reading");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i <= 255; i++)
|
||||
{
|
||||
printf ("%3d\n", i);
|
||||
fseek (fp, (long) -i, SEEK_END);
|
||||
if ((j = getc (fp)) != 256 - i)
|
||||
{
|
||||
printf ("SEEK_END failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) i, SEEK_SET))
|
||||
{
|
||||
puts ("Cannot SEEK_SET");
|
||||
break;
|
||||
}
|
||||
if ((j = getc (fp)) != i)
|
||||
{
|
||||
printf ("SEEK_SET failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) i, SEEK_SET))
|
||||
{
|
||||
puts ("Cannot SEEK_SET");
|
||||
break;
|
||||
}
|
||||
if (fseek (fp, (long) (i >= 128 ? -128 : 128), SEEK_CUR))
|
||||
{
|
||||
puts ("Cannot SEEK_CUR");
|
||||
break;
|
||||
}
|
||||
if ((j = getc (fp)) != (i >= 128 ? i - 128 : i + 128))
|
||||
{
|
||||
printf ("SEEK_CUR failed %d\n", j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
remove (TESTFILE);
|
||||
|
||||
puts ((i > 255) ? "Test succeeded." : "Test FAILED!");
|
||||
return (i > 255) ? 0 : 1;
|
||||
}
|
68
reactos/apps/tests/test_old/test-fwrite.c
Normal file
68
reactos/apps/tests/test_old/test-fwrite.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
FILE *f = tmpfile ();
|
||||
char obuf[99999], ibuf[sizeof obuf];
|
||||
char *line;
|
||||
size_t linesz;
|
||||
|
||||
if (! f)
|
||||
{
|
||||
perror ("tmpfile");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fputs ("line\n", f) == EOF)
|
||||
{
|
||||
perror ("fputs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset (obuf, 'z', sizeof obuf);
|
||||
memset (ibuf, 'y', sizeof ibuf);
|
||||
|
||||
if (fwrite (obuf, sizeof obuf, 1, f) != 1)
|
||||
{
|
||||
perror ("fwrite");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rewind (f);
|
||||
|
||||
line = NULL;
|
||||
linesz = 0;
|
||||
if (getline (&line, &linesz, f) != 5)
|
||||
{
|
||||
perror ("getline");
|
||||
return 1;
|
||||
}
|
||||
if (strcmp (line, "line\n"))
|
||||
{
|
||||
puts ("Lines differ. Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fread (ibuf, sizeof ibuf, 1, f) != 1)
|
||||
{
|
||||
perror ("fread");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp (ibuf, obuf, sizeof ibuf))
|
||||
{
|
||||
puts ("Buffers differ. Test FAILED!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
asprintf (&line, "\
|
||||
GDB is free software and you are welcome to distribute copies of it\n\
|
||||
under certain conditions; type \"show copying\" to see the conditions.\n\
|
||||
There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
|
||||
");
|
||||
|
||||
puts ("Test succeeded.");
|
||||
return 0;
|
||||
}
|
55
reactos/apps/tests/test_old/test-stdio.c
Normal file
55
reactos/apps/tests/test_old/test-stdio.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
char msg1[] = "testing _write\n";
|
||||
char msg2[] = "testing putchar.";
|
||||
char msg3[] = "testing printf.";
|
||||
char tmpbuf[255];
|
||||
FILE* f1;
|
||||
|
||||
write(1, msg1, strlen(msg1));
|
||||
|
||||
write(1, msg2, strlen(msg2));
|
||||
putchar('o'); putchar('k'); putchar('\n');
|
||||
|
||||
write(1, msg3, strlen(msg3));
|
||||
printf("ok\n");
|
||||
|
||||
printf("Testing fopen\n");
|
||||
f1 = fopen("tmp.txt","w+b");
|
||||
if (f1 == NULL)
|
||||
{
|
||||
printf("fopen failed\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fwrite\n");
|
||||
if (fwrite(msg1, 1, strlen(msg1)+1, f1) != (strlen(msg1)+1))
|
||||
{
|
||||
printf("fwrite failed\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fread\n");
|
||||
fseek(f1, 0, SEEK_SET);
|
||||
if (fread(tmpbuf, 1, strlen(msg1)+1, f1) != (strlen(msg1)+1))
|
||||
{
|
||||
printf("fread failed\n");
|
||||
return(1);
|
||||
}
|
||||
if (strcmp(tmpbuf,msg1) != 0)
|
||||
{
|
||||
printf("fread failed, data corrupt\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
printf("Testing fclose\n");
|
||||
if (fclose(f1) != 0)
|
||||
{
|
||||
printf("fclose failed\n");
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
129
reactos/apps/tests/test_old/test_rdwr.c
Normal file
129
reactos/apps/tests/test_old/test_rdwr.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* Copyright (C) 1991, 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
static const char hello[] = "Hello, world.\n";
|
||||
static const char replace[] = "Hewwo, world.\n";
|
||||
static const size_t replace_from = 2, replace_to = 4;
|
||||
char filename[FILENAME_MAX];
|
||||
char *name = strrchr (*argv, '/');
|
||||
char buf[BUFSIZ];
|
||||
FILE *f;
|
||||
int lose = 0;
|
||||
|
||||
if (name != NULL)
|
||||
++name;
|
||||
else
|
||||
name = *argv;
|
||||
|
||||
(void) sprintf (filename, "/tmp/%s.test", name);
|
||||
|
||||
f = fopen (filename, "w+");
|
||||
if (f == NULL)
|
||||
{
|
||||
perror (filename);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
(void) fputs (hello, f);
|
||||
rewind (f);
|
||||
(void) fgets (buf, sizeof (buf), f);
|
||||
rewind (f);
|
||||
(void) fputs (buf, f);
|
||||
rewind (f);
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < replace_from; ++i)
|
||||
{
|
||||
int c = getc (f);
|
||||
if (c == EOF)
|
||||
{
|
||||
printf ("EOF at %Zu.\n", i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
else if (c != hello[i])
|
||||
{
|
||||
printf ("Got '%c' instead of '%c' at %Zu.\n",
|
||||
(unsigned char) c, hello[i], i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
long int where = ftell (f);
|
||||
if (where == (long int) replace_from)
|
||||
{
|
||||
register size_t i;
|
||||
for (i = replace_from; i < replace_to; ++i)
|
||||
if (putc(replace[i], f) == EOF)
|
||||
{
|
||||
printf ("putc('%c') got %s at %Zu.\n",
|
||||
replace[i], strerror (errno), i);
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (where == -1L)
|
||||
{
|
||||
printf ("ftell got %s (should be at %Zu).\n",
|
||||
strerror (errno), replace_from);
|
||||
lose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("ftell returns %lu; should be %Zu.\n", where, replace_from);
|
||||
lose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lose)
|
||||
{
|
||||
rewind (f);
|
||||
if (fgets (buf, sizeof (buf), f) == NULL)
|
||||
{
|
||||
printf ("fgets got %s.\n", strerror(errno));
|
||||
lose = 1;
|
||||
}
|
||||
else if (strcmp (buf, replace))
|
||||
{
|
||||
printf ("Read \"%s\" instead of \"%s\".\n", buf, replace);
|
||||
lose = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (lose)
|
||||
printf ("Test FAILED! Losing file is \"%s\".\n", filename);
|
||||
else
|
||||
{
|
||||
(void) remove (filename);
|
||||
puts ("Test succeeded.");
|
||||
}
|
||||
|
||||
exit (lose ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
311
reactos/apps/tests/test_old/tst-printf.c
Normal file
311
reactos/apps/tests/test_old/tst-printf.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifdef BSD
|
||||
#include </usr/include/stdio.h>
|
||||
#define EXIT_SUCCESS 0
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
|
||||
void rfg1 (void);
|
||||
void rfg2 (void);
|
||||
|
||||
|
||||
void
|
||||
fmtchk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
void
|
||||
fmtst1chk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 4, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
void
|
||||
fmtst2chk (const char *fmt)
|
||||
{
|
||||
(void) fputs(fmt, stdout);
|
||||
(void) printf(":\t`");
|
||||
(void) printf(fmt, 4, 4, 0x12);
|
||||
(void) printf("'\n");
|
||||
}
|
||||
|
||||
/* This page is covered by the following copyright: */
|
||||
|
||||
/* (C) Copyright C E Chew
|
||||
*
|
||||
* Feel free to copy, use and distribute this software provided:
|
||||
*
|
||||
* 1. you do not pretend that you wrote it
|
||||
* 2. you leave this copyright notice intact.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracted from exercise.c for glibc-1.05 bug report by Bruce Evans.
|
||||
*/
|
||||
|
||||
#define DEC -123
|
||||
#define INT 255
|
||||
#define UNS (~0)
|
||||
|
||||
/* Formatted Output Test
|
||||
*
|
||||
* This exercises the output formatting code.
|
||||
*/
|
||||
|
||||
void
|
||||
fp_test (void)
|
||||
{
|
||||
int i, j, k, l;
|
||||
char buf[7];
|
||||
char *prefix = buf;
|
||||
char tp[20];
|
||||
|
||||
puts("\nFormatted output test");
|
||||
printf("prefix 6d 6o 6x 6X 6u\n");
|
||||
strcpy(prefix, "%");
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (k = 0; k < 2; k++) {
|
||||
for (l = 0; l < 2; l++) {
|
||||
strcpy(prefix, "%");
|
||||
if (i == 0) strcat(prefix, "-");
|
||||
if (j == 0) strcat(prefix, "+");
|
||||
if (k == 0) strcat(prefix, "#");
|
||||
if (l == 0) strcat(prefix, "0");
|
||||
printf("%5s |", prefix);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6d |");
|
||||
printf(tp, DEC);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6o |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6x |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6X |");
|
||||
printf(tp, INT);
|
||||
strcpy(tp, prefix);
|
||||
strcat(tp, "6u |");
|
||||
printf(tp, UNS);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%10s\n", (char *) NULL);
|
||||
printf("%-10s\n", (char *) NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
static char shortstr[] = "Hi, Z.";
|
||||
static char longstr[] = "Good morning, Doctor Chandra. This is Hal. \
|
||||
I am ready for my first lesson today.";
|
||||
|
||||
fmtchk("%.4x");
|
||||
fmtchk("%04x");
|
||||
fmtchk("%4.4x");
|
||||
fmtchk("%04.4x");
|
||||
fmtchk("%4.3x");
|
||||
fmtchk("%04.3x");
|
||||
|
||||
fmtst1chk("%.*x");
|
||||
fmtst1chk("%0*x");
|
||||
fmtst2chk("%*.*x");
|
||||
fmtst2chk("%0*.*x");
|
||||
|
||||
#ifndef BSD
|
||||
printf("bad format:\t\"%b\"\n");
|
||||
printf("nil pointer (padded):\t\"%10p\"\n", (void *) NULL);
|
||||
#endif
|
||||
|
||||
printf("decimal negative:\t\"%d\"\n", -2345);
|
||||
printf("octal negative:\t\"%o\"\n", -2345);
|
||||
printf("hex negative:\t\"%x\"\n", -2345);
|
||||
printf("long decimal number:\t\"%ld\"\n", -123456L);
|
||||
printf("long octal negative:\t\"%lo\"\n", -2345L);
|
||||
printf("long unsigned decimal number:\t\"%lu\"\n", -123456L);
|
||||
printf("zero-padded LDN:\t\"%010ld\"\n", -123456L);
|
||||
printf("left-adjusted ZLDN:\t\"%-010ld\"\n", -123456);
|
||||
printf("space-padded LDN:\t\"%10ld\"\n", -123456L);
|
||||
printf("left-adjusted SLDN:\t\"%-10ld\"\n", -123456L);
|
||||
|
||||
printf("zero-padded string:\t\"%010s\"\n", shortstr);
|
||||
printf("left-adjusted Z string:\t\"%-010s\"\n", shortstr);
|
||||
printf("space-padded string:\t\"%10s\"\n", shortstr);
|
||||
printf("left-adjusted S string:\t\"%-10s\"\n", shortstr);
|
||||
printf("null string:\t\"%s\"\n", (char *)NULL);
|
||||
printf("limited string:\t\"%.22s\"\n", longstr);
|
||||
|
||||
printf("e-style >= 1:\t\"%e\"\n", 12.34);
|
||||
printf("e-style >= .1:\t\"%e\"\n", 0.1234);
|
||||
printf("e-style < .1:\t\"%e\"\n", 0.001234);
|
||||
printf("e-style big:\t\"%.60e\"\n", 1e20);
|
||||
printf ("e-style == .1:\t\"%e\"\n", 0.1);
|
||||
printf("f-style >= 1:\t\"%f\"\n", 12.34);
|
||||
printf("f-style >= .1:\t\"%f\"\n", 0.1234);
|
||||
printf("f-style < .1:\t\"%f\"\n", 0.001234);
|
||||
printf("g-style >= 1:\t\"%g\"\n", 12.34);
|
||||
printf("g-style >= .1:\t\"%g\"\n", 0.1234);
|
||||
printf("g-style < .1:\t\"%g\"\n", 0.001234);
|
||||
printf("g-style big:\t\"%.60g\"\n", 1e20);
|
||||
|
||||
printf (" %6.5f\n", .099999999860301614);
|
||||
printf (" %6.5f\n", .1);
|
||||
printf ("x%5.4fx\n", .5);
|
||||
|
||||
printf ("%#03x\n", 1);
|
||||
|
||||
{
|
||||
double d = FLT_MIN;
|
||||
int niter = 17;
|
||||
|
||||
while (niter-- != 0)
|
||||
printf ("%.17e\n", d / 2);
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
printf ("%15.5e\n", 4.9406564584124654e-324);
|
||||
|
||||
#define FORMAT "|%12.4f|%12.4e|%12.4g|\n"
|
||||
printf (FORMAT, 0.0, 0.0, 0.0);
|
||||
printf (FORMAT, 1.0, 1.0, 1.0);
|
||||
printf (FORMAT, -1.0, -1.0, -1.0);
|
||||
printf (FORMAT, 100.0, 100.0, 100.0);
|
||||
printf (FORMAT, 1000.0, 1000.0, 1000.0);
|
||||
printf (FORMAT, 10000.0, 10000.0, 10000.0);
|
||||
printf (FORMAT, 12345.0, 12345.0, 12345.0);
|
||||
printf (FORMAT, 100000.0, 100000.0, 100000.0);
|
||||
printf (FORMAT, 123456.0, 123456.0, 123456.0);
|
||||
#undef FORMAT
|
||||
|
||||
{
|
||||
char buf[20];
|
||||
printf ("sprintf (\"%%30s\", \"foo\") == %d, \"%.*s\"\n",
|
||||
sprintf (buf, "%30s", "foo"), sizeof (buf), buf);
|
||||
}
|
||||
|
||||
fp_test ();
|
||||
|
||||
printf ("%e should be 1.234568e+06\n", 1234567.8);
|
||||
printf ("%f should be 1234567.800000\n", 1234567.8);
|
||||
printf ("%g should be 1.23457e+06\n", 1234567.8);
|
||||
printf ("%g should be 123.456\n", 123.456);
|
||||
printf ("%g should be 1e+06\n", 1000000.0);
|
||||
printf ("%g should be 10\n", 10.0);
|
||||
printf ("%g should be 0.02\n", 0.02);
|
||||
|
||||
{
|
||||
double x=1.0;
|
||||
printf("%.17f\n",(1.0/x/10.0+1.0)*x-x);
|
||||
}
|
||||
|
||||
puts ("--- Should be no further output. ---");
|
||||
rfg1 ();
|
||||
rfg2 ();
|
||||
|
||||
{
|
||||
char buf[200];
|
||||
int result;
|
||||
|
||||
sprintf(buf,"%*s%*s%*s",-1,"one",-20,"two",-30,"three");
|
||||
|
||||
result = strcmp (buf,
|
||||
"onetwo three ");
|
||||
|
||||
puts (result != 0 ? "Test failed!" : "Test ok.");
|
||||
return result != 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rfg1 (void)
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
sprintf (buf, "%5.s", "xyz");
|
||||
if (strcmp (buf, " ") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " ");
|
||||
sprintf (buf, "%5.f", 33.3);
|
||||
if (strcmp (buf, " 33") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 33");
|
||||
sprintf (buf, "%8.e", 33.3e7);
|
||||
if (strcmp (buf, " 3e+08") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3e+08");
|
||||
sprintf (buf, "%8.E", 33.3e7);
|
||||
if (strcmp (buf, " 3E+08") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3E+08");
|
||||
sprintf (buf, "%.g", 33.3);
|
||||
if (strcmp (buf, "3e+01") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3e+01");
|
||||
sprintf (buf, "%.G", 33.3);
|
||||
if (strcmp (buf, "3E+01") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3E+01");
|
||||
}
|
||||
|
||||
void
|
||||
rfg2 (void)
|
||||
{
|
||||
int prec;
|
||||
char buf[100];
|
||||
|
||||
prec = 0;
|
||||
sprintf (buf, "%.*g", prec, 3.3);
|
||||
if (strcmp (buf, "3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3");
|
||||
prec = 0;
|
||||
sprintf (buf, "%.*G", prec, 3.3);
|
||||
if (strcmp (buf, "3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, "3");
|
||||
prec = 0;
|
||||
sprintf (buf, "%7.*G", prec, 3.33);
|
||||
if (strcmp (buf, " 3") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 3");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*o", prec, 33);
|
||||
if (strcmp (buf, " 041") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 041");
|
||||
prec = 7;
|
||||
sprintf (buf, "%09.*u", prec, 33);
|
||||
if (strcmp (buf, " 0000033") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 0000033");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*x", prec, 33);
|
||||
if (strcmp (buf, " 021") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 021");
|
||||
prec = 3;
|
||||
sprintf (buf, "%04.*X", prec, 33);
|
||||
if (strcmp (buf, " 021") != 0)
|
||||
printf ("got: '%s', expected: '%s'\n", buf, " 021");
|
||||
}
|
56
reactos/apps/tests/test_old/tstdiomisc.c
Normal file
56
reactos/apps/tests/test_old/tstdiomisc.c
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
t1 (void)
|
||||
{
|
||||
int n = -1;
|
||||
sscanf ("abc ", "abc %n", &n);
|
||||
printf ("t1: count=%d\n", n);
|
||||
|
||||
return n != 5;
|
||||
}
|
||||
|
||||
int
|
||||
t2 (void)
|
||||
{
|
||||
int result = 0;
|
||||
int n;
|
||||
long N;
|
||||
int retval;
|
||||
#define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \
|
||||
VAR = -1; \
|
||||
retval = sscanf (INPUT, FORMAT, &VAR); \
|
||||
printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \
|
||||
INPUT, FORMAT, retval, (long int) VAR); \
|
||||
result |= retval != EXP_RES || VAR != EXP_VAL
|
||||
|
||||
SCAN ("12345", "%ld", N, 1, 12345);
|
||||
SCAN ("12345", "%llllld", N, 0, -1);
|
||||
SCAN ("12345", "%LLLLLd", N, 0, -1);
|
||||
SCAN ("test ", "%*s%n", n, 0, 4);
|
||||
SCAN ("test ", "%2*s%n", n, 0, -1);
|
||||
SCAN ("12 ", "%l2d", n, 0, -1);
|
||||
SCAN ("12 ", "%2ld", N, 1, 12);
|
||||
|
||||
n = -1;
|
||||
N = -1;
|
||||
retval = sscanf ("1 1", "%d %Z", &n, &N);
|
||||
printf ("sscanf (\"1 1\", \"%%d %%Z\", &n, &N) => %d, n = %d, N = %ld\n", \
|
||||
retval, n, N); \
|
||||
result |= retval != 1 || n != 1 || N != -1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result |= t1 ();
|
||||
result |= t2 ();
|
||||
|
||||
result |= fflush (stdout) == EOF;
|
||||
|
||||
return result;
|
||||
}
|
41
reactos/apps/tests/thread/makefile
Normal file
41
reactos/apps/tests/thread/makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
PROGS = thread
|
||||
|
||||
all: $(PROGS:%=%.exe)
|
||||
|
||||
.phony: all
|
||||
|
||||
clean: $(PROGS:%=%_clean)
|
||||
|
||||
$(PROGS:%=%_clean): %_clean:
|
||||
- $(RM) $*.o
|
||||
- $(RM) $*.exe
|
||||
- $(RM) $*.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: # $(PROGS:%=$(FLOPPY_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%.exe): $(FLOPPY_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe $(FLOPPY_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe $(FLOPPY_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%.exe)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%.exe): ../../$(DIST_DIR)/apps/%.exe: %.exe
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $*.exe ..\..\$(DIST_DIR)\apps\$*.exe
|
||||
else
|
||||
$(CP) $*.exe ../../$(DIST_DIR)/apps/$*.exe
|
||||
endif
|
||||
|
||||
thread.exe: thread.c
|
||||
$(CC) $(CFLAGS) thread.c -lkernel32 -o thread.exe
|
||||
$(NM) --numeric-sort thread.exe > thread.sym
|
||||
|
||||
include ../../rules.mak
|
46
reactos/apps/tests/thread/thread.c
Normal file
46
reactos/apps/tests/thread/thread.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define NR_THREADS (10)
|
||||
|
||||
ULONG nr;
|
||||
|
||||
DWORD WINAPI thread_main1(LPVOID param)
|
||||
{
|
||||
ULONG s;
|
||||
|
||||
printf("Thread %d running\n", (DWORD)param);
|
||||
s = nr = ((nr * 1103515245) + 12345) & 0x7fffffff;
|
||||
s = s % 10;
|
||||
printf("s %d\n", s);
|
||||
Sleep(s);
|
||||
printf("Thread %d finished\n", (DWORD)param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD i=0;
|
||||
DWORD id;
|
||||
ULONG nr;
|
||||
|
||||
nr = atoi(argv[1]);
|
||||
printf("Seed %d\n", nr);
|
||||
|
||||
printf("Creating %d threads...\n",NR_THREADS*2);
|
||||
for (i=0;i<NR_THREADS;i++)
|
||||
{
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
}
|
||||
|
||||
printf("All threads created...\n");
|
||||
for(;;);
|
||||
return 0;
|
||||
}
|
2
reactos/apps/utils/buildno/.cvsignore
Normal file
2
reactos/apps/utils/buildno/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
buildno
|
||||
buildno.exe
|
26
reactos/apps/utils/buildno/Makefile
Normal file
26
reactos/apps/utils/buildno/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
# $Id: Makefile,v 1.3 1999/11/12 12:01:09 dwelch Exp $
|
||||
#
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
TARGETNAME=buildno
|
||||
CLEAN_FILES= $(TARGETNAME).o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).sym
|
||||
|
||||
all: $(TARGETNAME)$(EXE_POSTFIX)
|
||||
$(EXE_PREFIX)$(TARGETNAME)$(EXE_POSTFIX) -q
|
||||
|
||||
|
||||
$(TARGETNAME)$(EXE_POSTFIX): $(TARGETNAME).c ../../include/reactos/version.h
|
||||
$(NATIVE_CC) -I../../include -o $(TARGETNAME)$(EXE_POSTFIX) $(TARGETNAME).c
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
$(RM) $(TARGETNAME).o
|
||||
$(RM) $(TARGETNAME).sym
|
||||
$(RM) $(TARGETNAME)$(EXE_POSTFIX)
|
||||
|
||||
.phony: clean
|
||||
|
||||
include ../../rules.mak
|
||||
|
||||
# EOF
|
262
reactos/apps/utils/buildno/buildno.c
Normal file
262
reactos/apps/utils/buildno/buildno.c
Normal file
@@ -0,0 +1,262 @@
|
||||
/* $Id: buildno.c,v 1.2 1999/12/26 20:21:02 ea Exp $
|
||||
*
|
||||
* buildno - Generate the build number for ReactOS
|
||||
*
|
||||
* Copyright (c) 1999 Emanuele Aliberti
|
||||
*
|
||||
*
|
||||
* It assumes the last release date is defined in
|
||||
* <reactos/version.h> as a macro named
|
||||
*
|
||||
* KERNEL_RELEASE_DATE
|
||||
*
|
||||
* as a 32-bit unsigned long YYYYMMDD (UTC).
|
||||
*
|
||||
* The build number is the number of full days
|
||||
* elapsed since the last release date (UTC).
|
||||
*
|
||||
* The build number is stored in the file
|
||||
* <reactos/buildno.h> as a set of macros:
|
||||
*
|
||||
* KERNEL_VERSION_BUILD
|
||||
* KERNEL_VERSION_BUILD_STR
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <reactos/version.h>
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* File to (over)write */
|
||||
#define BUILDNO_INCLUDE_FILE "../../include/reactos/buildno.h"
|
||||
|
||||
static char * argv0 = "";
|
||||
|
||||
|
||||
int
|
||||
elapsed_days (
|
||||
time_t t_today,
|
||||
time_t t_release_day
|
||||
)
|
||||
{
|
||||
double seconds = difftime (t_today, t_release_day);
|
||||
double days = seconds / (double) 86400.0;
|
||||
char buf [32];
|
||||
char * dot = buf;
|
||||
|
||||
sprintf (buf, "%f", days );
|
||||
|
||||
while ( *dot && *dot != '.') ++dot;
|
||||
*dot = '\0';
|
||||
|
||||
return atol (buf);
|
||||
}
|
||||
|
||||
void
|
||||
write_h (int build)
|
||||
{
|
||||
FILE *h = NULL;
|
||||
|
||||
h = fopen ( BUILDNO_INCLUDE_FILE, "w");
|
||||
if (!h)
|
||||
{
|
||||
fprintf (
|
||||
stderr,
|
||||
"%s: can not create file \"%s\"!\n",
|
||||
argv0,
|
||||
BUILDNO_INCLUDE_FILE
|
||||
);
|
||||
return;
|
||||
}
|
||||
fprintf (
|
||||
h,
|
||||
"/* Do not edit - Machine generated */\n"
|
||||
);
|
||||
|
||||
fprintf (h, "#ifndef _INC_REACTOS_BUILDNO\n" );
|
||||
fprintf (h, "#define _INC_REACTOS_BUILDNO\n" );
|
||||
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_BUILD\t%d\n",
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_BUILD_STR\t\"%d\"\n",
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_RELEASE_RC\t\"%d.%d.%d.%d\\0\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_RELEASE_STR\t\"%d.%d.%d.%d\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_RC\t\"%d.%d.%d\\0\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#define KERNEL_VERSION_STR\t\"%d.%d.%d\"\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL
|
||||
);
|
||||
fprintf (
|
||||
h,
|
||||
"#endif\n/* EOF */\n"
|
||||
);
|
||||
|
||||
fclose (h);
|
||||
}
|
||||
|
||||
void
|
||||
usage (void)
|
||||
{
|
||||
fprintf (
|
||||
stderr,
|
||||
"Usage: %s [-q]\n",
|
||||
argv0
|
||||
);
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char * argv [])
|
||||
{
|
||||
int quiet = FALSE;
|
||||
|
||||
int year = 0;
|
||||
int month = 0;
|
||||
int day = 0;
|
||||
int build = 0;
|
||||
|
||||
time_t t0 = 0;
|
||||
struct tm t0_tm = {0};
|
||||
time_t t1 = 0;
|
||||
struct tm * t1_tm = NULL;
|
||||
|
||||
argv0 = argv[0];
|
||||
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (argv[1][0] == '-')
|
||||
{
|
||||
if (argv[1][1] == 'q')
|
||||
{
|
||||
quiet = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usage ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
/*
|
||||
* We are building TODAY!
|
||||
*/
|
||||
time (& t0);
|
||||
/*
|
||||
* "Parse" the release date.
|
||||
*/
|
||||
day = KERNEL_RELEASE_DATE % 100;
|
||||
month = ( ( KERNEL_RELEASE_DATE
|
||||
% 10000
|
||||
)
|
||||
- day
|
||||
)
|
||||
/ 100;
|
||||
year =
|
||||
( KERNEL_RELEASE_DATE
|
||||
- (month * 100)
|
||||
- day
|
||||
)
|
||||
/ 10000;
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf ( "\n\
|
||||
ReactOS Build Number Generator\n\n\
|
||||
Last release: %4d-%02d-%02d\n",
|
||||
year,
|
||||
month,
|
||||
day
|
||||
);
|
||||
}
|
||||
t0_tm.tm_year = year - ((year > 1999) ? 2000 : 1900);
|
||||
t0_tm.tm_mon = month;
|
||||
t0_tm.tm_mday = day;
|
||||
|
||||
t0 = mktime (& t0_tm);
|
||||
|
||||
time (& t1); /* current build time */
|
||||
t1_tm = gmtime (& t1);
|
||||
|
||||
t1_tm->tm_year +=
|
||||
(t1_tm->tm_year < 70)
|
||||
? 2000
|
||||
: 1900;
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf (
|
||||
"Current date: %4d-%02d-%02d\n\n",
|
||||
t1_tm->tm_year,
|
||||
t1_tm->tm_mon,
|
||||
t1_tm->tm_mday
|
||||
);
|
||||
}
|
||||
/*
|
||||
* Compute delta days.
|
||||
*/
|
||||
build = elapsed_days (t1, t0);
|
||||
|
||||
if (FALSE == quiet)
|
||||
{
|
||||
printf (
|
||||
"Build number: %d (elapsed days since last release)\n",
|
||||
build
|
||||
);
|
||||
printf (
|
||||
"ROS Version : %d.%d.%d.%d\n",
|
||||
KERNEL_VERSION_MAJOR,
|
||||
KERNEL_VERSION_MINOR,
|
||||
KERNEL_VERSION_PATCH_LEVEL,
|
||||
build
|
||||
);
|
||||
}
|
||||
/*
|
||||
* (Over)write the include file.
|
||||
*/
|
||||
write_h (build);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
26
reactos/apps/utils/cat/cat.c
Normal file
26
reactos/apps/utils/cat/cat.c
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
FILE* in;
|
||||
char ch;
|
||||
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
in = fopen(argv[i],"r");
|
||||
if (in == NULL)
|
||||
{
|
||||
printf("Failed to open file %s\n", argv[i]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while ((ch = fgetc(in)) != EOF)
|
||||
{
|
||||
putchar(ch);
|
||||
}
|
||||
fclose(in);
|
||||
}
|
||||
return 0;
|
||||
}
|
42
reactos/apps/utils/cat/makefile
Normal file
42
reactos/apps/utils/cat/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= cat.o
|
||||
PROGS= cat.exe
|
||||
|
||||
all: cat.exe
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) cat.o
|
||||
- $(RM) cat.exe
|
||||
- $(RM) cat.sym
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
.PHONY: floppy dist
|
||||
|
||||
cat.exe: $(OBJECTS) $(LIBS)
|
||||
$(CC) $(OBJECTS) -o cat.exe
|
||||
$(NM) --numeric-sort cat.exe > cat.sym
|
||||
|
||||
include ../../rules.mak
|
42
reactos/apps/utils/shell/makefile
Normal file
42
reactos/apps/utils/shell/makefile
Normal file
@@ -0,0 +1,42 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
OBJECTS= ../common/crt0.o shell.o
|
||||
PROGS= shell.exe
|
||||
LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
|
||||
CLEAN_FILES= shell.o shell.exe shell.sym
|
||||
|
||||
BASE_CFLAGS = -I../../include
|
||||
|
||||
all: shell.exe
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||
- $(RM) $*
|
||||
|
||||
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||
|
||||
floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
|
||||
|
||||
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $* ..\..\$(DIST_DIR)\apps\$*
|
||||
else
|
||||
$(CP) $* ../../$(DIST_DIR)/apps/$*
|
||||
endif
|
||||
|
||||
shell.exe: $(OBJECTS) $(LIBS)
|
||||
$(CC) -specs=../../specs $(OBJECTS) $(LIBS) -lgcc -o shell.exe
|
||||
$(NM) --numeric-sort shell.exe > shell.sym
|
||||
|
||||
include ../../rules.mak
|
389
reactos/apps/utils/shell/shell.c
Normal file
389
reactos/apps/utils/shell/shell.c
Normal file
@@ -0,0 +1,389 @@
|
||||
#include <ddk/ntddk.h>
|
||||
#include <windows.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
HANDLE InputHandle, OutputHandle;
|
||||
|
||||
void debug_printf(char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255];
|
||||
|
||||
va_start(args,fmt);
|
||||
vsprintf(buffer,fmt,args);
|
||||
WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ExecuteVer(void)
|
||||
{
|
||||
debug_printf(
|
||||
"Reactos Simple Shell\n(compiled on %s, at %s)\n",
|
||||
__DATE__,
|
||||
__TIME__
|
||||
);
|
||||
}
|
||||
|
||||
void ExecuteCd(char* cmdline)
|
||||
{
|
||||
if (!SetCurrentDirectoryA(cmdline))
|
||||
{
|
||||
debug_printf("Invalid directory\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteDir(char* cmdline)
|
||||
{
|
||||
HANDLE shandle;
|
||||
WIN32_FIND_DATA FindData;
|
||||
int nFile=0, nRep=0;
|
||||
FILETIME fTime;
|
||||
SYSTEMTIME sTime;
|
||||
|
||||
shandle = FindFirstFile("*",&FindData);
|
||||
|
||||
if (shandle==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
debug_printf("Invalid directory\n");
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
debug_printf("%-15.15s",FindData.cAlternateFileName);
|
||||
if(FindData.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
|
||||
debug_printf("<DIR> "),nRep++;
|
||||
else
|
||||
debug_printf(" %10d ",FindData.nFileSizeLow),nFile++;
|
||||
|
||||
FileTimeToLocalFileTime(&FindData.ftLastWriteTime ,&fTime);
|
||||
FileTimeToSystemTime(&fTime, &sTime);
|
||||
debug_printf("%02d/%02d/%04d %02d:%02d:%02d "
|
||||
,sTime.wMonth,sTime.wDay,sTime.wYear
|
||||
,sTime.wHour,sTime.wMinute,sTime.wSecond);
|
||||
|
||||
debug_printf("%s\n",FindData.cFileName);
|
||||
} while(FindNextFile(shandle,&FindData));
|
||||
debug_printf("\n %d files\n %d directories\n\n",nFile,nRep);
|
||||
FindClose(shandle);
|
||||
}
|
||||
|
||||
|
||||
void ExecuteReboot(char* cmdline)
|
||||
{
|
||||
NtShutdownSystem (ShutdownReboot);
|
||||
}
|
||||
|
||||
|
||||
void ExecuteType(char* cmdline)
|
||||
{
|
||||
HANDLE FileHandle;
|
||||
char c;
|
||||
DWORD Result;
|
||||
|
||||
FileHandle = CreateFile(cmdline,
|
||||
FILE_GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (FileHandle == NULL)
|
||||
{
|
||||
debug_printf("Unknown file\n");
|
||||
return;
|
||||
}
|
||||
while (ReadFile(FileHandle,
|
||||
&c,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("%c",c);
|
||||
c = 0;
|
||||
}
|
||||
CloseHandle(FileHandle);
|
||||
}
|
||||
|
||||
int ExecuteProcess(char* name, char* cmdline, BOOL detached)
|
||||
{
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFO StartupInfo;
|
||||
// char arguments;
|
||||
BOOL ret;
|
||||
|
||||
memset(&StartupInfo, 0, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof (STARTUPINFO);
|
||||
StartupInfo.lpTitle = name;
|
||||
|
||||
ret = CreateProcessA(name,
|
||||
cmdline,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
((TRUE == detached)
|
||||
? DETACHED_PROCESS
|
||||
: CREATE_NEW_CONSOLE
|
||||
),
|
||||
NULL,
|
||||
NULL,
|
||||
& StartupInfo,
|
||||
& ProcessInformation
|
||||
);
|
||||
if (TRUE == detached)
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
debug_printf("%s detached:\n"
|
||||
"\thProcess = %08X\n"
|
||||
"\thThread = %08X\n"
|
||||
"\tPID = %d\n"
|
||||
"\tTID = %d\n\n",
|
||||
name,
|
||||
ProcessInformation.hProcess,
|
||||
ProcessInformation.hThread,
|
||||
ProcessInformation.dwProcessId,
|
||||
ProcessInformation.dwThreadId);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf("Could not detach %s\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
debug_printf("ProcessInformation.hThread %x\n",
|
||||
ProcessInformation.hThread);
|
||||
// CloseHandle(ProcessInformation.hThread);
|
||||
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
debug_printf("Thandle %x\n", ProcessInformation.hThread);
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void ExecuteStart(char* CommandLine)
|
||||
{
|
||||
char *ImageName = CommandLine;
|
||||
|
||||
for ( ;
|
||||
( (*CommandLine)
|
||||
&& (*CommandLine != ' ')
|
||||
&& (*CommandLine != '\t')
|
||||
);
|
||||
CommandLine++
|
||||
);
|
||||
*CommandLine++ = '\0';
|
||||
while ( (*CommandLine)
|
||||
&& ( (*CommandLine == ' ')
|
||||
|| (*CommandLine == '\t')
|
||||
)
|
||||
);
|
||||
ExecuteProcess(
|
||||
ImageName,
|
||||
CommandLine,
|
||||
TRUE
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
ExecuteKill(char * lpPid)
|
||||
{
|
||||
HANDLE hProcess;
|
||||
DWORD dwProcessId;
|
||||
|
||||
dwProcessId = (DWORD) atol(lpPid);
|
||||
debug_printf("dwProcessId %d\n",dwProcessId);
|
||||
hProcess = OpenProcess(
|
||||
PROCESS_TERMINATE,
|
||||
FALSE,
|
||||
dwProcessId
|
||||
);
|
||||
if (NULL == hProcess)
|
||||
{
|
||||
debug_printf(
|
||||
"Could not open the process with PID = %d\n",
|
||||
dwProcessId
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (FALSE == TerminateProcess(
|
||||
hProcess,
|
||||
0
|
||||
)
|
||||
) {
|
||||
debug_printf(
|
||||
"Could not terminate the process with PID = %d\n",
|
||||
dwProcessId
|
||||
);
|
||||
}
|
||||
CloseHandle(hProcess);
|
||||
return;
|
||||
}
|
||||
|
||||
void ExecuteCommand(char* line)
|
||||
{
|
||||
char* cmd;
|
||||
char* tail;
|
||||
|
||||
if (isalpha(line[0]) && line[1] == ':' && line[2] == 0)
|
||||
{
|
||||
line[2] = '\\';
|
||||
line[3] = 0;
|
||||
SetCurrentDirectoryA(line);
|
||||
return;
|
||||
}
|
||||
|
||||
tail = line;
|
||||
while ((*tail)!=' ' && (*tail)!=0)
|
||||
{
|
||||
tail++;
|
||||
}
|
||||
if ((*tail)==' ')
|
||||
{
|
||||
*tail = 0;
|
||||
tail++;
|
||||
}
|
||||
cmd = line;
|
||||
|
||||
|
||||
if (cmd==NULL || *cmd == '\0' )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"cd")==0)
|
||||
{
|
||||
ExecuteCd(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"dir")==0)
|
||||
{
|
||||
ExecuteDir(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"kill")==0)
|
||||
{
|
||||
ExecuteKill(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"reboot")==0)
|
||||
{
|
||||
ExecuteReboot(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"type")==0)
|
||||
{
|
||||
ExecuteType(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"ver")==0)
|
||||
{
|
||||
ExecuteVer();
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"validate")==0)
|
||||
{
|
||||
debug_printf("Validating heap...");
|
||||
if (HeapValidate(GetProcessHeap(),0,NULL))
|
||||
{
|
||||
debug_printf("succeeded\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_printf("failed\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"start") == 0)
|
||||
{
|
||||
ExecuteStart(tail);
|
||||
return;
|
||||
}
|
||||
if (strcmp(cmd,"exit")==0)
|
||||
{
|
||||
ExitProcess(0);
|
||||
return;
|
||||
}
|
||||
if (ExecuteProcess(cmd,tail,FALSE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
debug_printf("Unknown command\n");
|
||||
}
|
||||
|
||||
void ReadLine(char* line)
|
||||
{
|
||||
// KEY_EVENT_RECORD KeyEvent;
|
||||
DWORD Result;
|
||||
UCHAR CurrentDir[255];
|
||||
char ch;
|
||||
int length = 0;
|
||||
|
||||
GetCurrentDirectoryA(255,CurrentDir);
|
||||
debug_printf("%s>", CurrentDir);
|
||||
|
||||
do
|
||||
{
|
||||
if (!ReadConsoleA(InputHandle,
|
||||
&ch,
|
||||
1,
|
||||
&Result,
|
||||
NULL))
|
||||
{
|
||||
debug_printf("Failed to read from console\n");
|
||||
for(;;);
|
||||
}
|
||||
switch (ch)
|
||||
{
|
||||
case '\b':
|
||||
if (length > 0)
|
||||
{
|
||||
debug_printf("\b \b");
|
||||
line--;
|
||||
length--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
debug_printf("%c", ch);
|
||||
*line = ch;
|
||||
line++;
|
||||
length++;
|
||||
}
|
||||
} while (ch != '\n');
|
||||
line--;
|
||||
*line = 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static char line[255];
|
||||
|
||||
AllocConsole();
|
||||
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
debug_printf("Shell Starting...\n");
|
||||
|
||||
SetCurrentDirectoryA("C:\\");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ReadLine(line);
|
||||
ExecuteCommand(line);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
1
reactos/boot.bat
Normal file
1
reactos/boot.bat
Normal file
@@ -0,0 +1 @@
|
||||
loadros ntoskrnl.exe ide.sys vfatfs.sys
|
32
reactos/bootflop.bat
Normal file
32
reactos/bootflop.bat
Normal file
@@ -0,0 +1,32 @@
|
||||
@ECHO OFF
|
||||
|
||||
:
|
||||
: copy files to HD...
|
||||
:
|
||||
COPY /Y A:\DRIVERS\*.SYS C:\reactos\system32\drivers > NUL:
|
||||
COPY /Y A:\DLLS\*.DLL C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\APPS\*.EXE C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\SUBSYS\*.EXE C:\reactos\system32 > NUL:
|
||||
COPY /Y A:\SUBSYS\*.DLL C:\reactos\system32 > NUL:
|
||||
:
|
||||
: present a menu to the booter...
|
||||
:
|
||||
: ECHO 1) IDE,VFatFSD
|
||||
: ECHO 2) No Drivers
|
||||
: CHOICE /C:123 /T:1,3 "Select kernel boot config"
|
||||
: IF ERRORLEVEL 2 GOTO :L2
|
||||
|
||||
:L1
|
||||
CLS
|
||||
LOADROS NTOSKRNL.EXE DRIVERS\IDE.SYS DRIVERS\VFATFSD.SYS
|
||||
GOTO :END
|
||||
|
||||
:L2
|
||||
CLS
|
||||
LOADROS NTOSKRNL.EXE
|
||||
GOTO :END
|
||||
|
||||
:END
|
||||
EXIT
|
||||
|
||||
|
22
reactos/doc/DIRS
Normal file
22
reactos/doc/DIRS
Normal file
@@ -0,0 +1,22 @@
|
||||
DIRECTORIES
|
||||
|
||||
system : compiled versions of the various system components and
|
||||
libraries
|
||||
ntoskrnl : kernel source
|
||||
ntoskrnl/hal : hardware abstraction layer source
|
||||
ntoskrnl/mm : memory managment subsystem source
|
||||
ntoskrnl/io : IO manager subsystem source
|
||||
ntoskrnl/ke : kernel source
|
||||
include : win32 headers
|
||||
include/internal : kernel private header files
|
||||
include/ntdll : system library private header files
|
||||
include/kernel32 : system library private header files
|
||||
include/ddk : header files for modules
|
||||
lib/ntdll : NT dll source
|
||||
lib/kernel32 : kernel32 source
|
||||
doc : documentation
|
||||
loaders/dos : DOS based loader
|
||||
loaders/boot : boot loader
|
||||
services : various services (device drivers, filesystems etc)
|
||||
services/dd : device drivers
|
||||
services/fs : file systems
|
130
reactos/doc/HACKING
Normal file
130
reactos/doc/HACKING
Normal file
@@ -0,0 +1,130 @@
|
||||
* Introduction
|
||||
|
||||
Having successfully built ReactOS and been amazed by what it does, you're
|
||||
now desperate to fill in some of the omissions, this document shows you how.
|
||||
|
||||
* Prerequisites
|
||||
|
||||
A working knowledge of NT driver development is useful for understanding the
|
||||
kernel and some of its abstractions. The NT4 ddk is available for free
|
||||
download from http://www.microsoft.com/hwdev/. The Windows 98 and Windows
|
||||
2000 DDKs are also available but the NT4 one is the most useful. See
|
||||
Legal Stuff below however.
|
||||
|
||||
There are a number of books on NT driver development, I would recommend
|
||||
'Windows NT Device Driver Development' (http://www.osr.com/book/) since OSR
|
||||
seem to know their stuff. There is only one book on NT filesystem
|
||||
development 'Windows NT File System Internals'. Please don't buy any of
|
||||
these books unless you need to, and can afford it.
|
||||
|
||||
These mailing lists and newsgroups are useful for NT internals related
|
||||
questions,
|
||||
ntfsd@atria.com, ntdev@atria.com
|
||||
(subscribe by email to majordomo@atria.com)
|
||||
comp.os.????
|
||||
microsoft.public.????
|
||||
|
||||
* Style
|
||||
|
||||
There is no coding style used for ReactOS, however the following guidelines
|
||||
make things easier
|
||||
|
||||
Include information at the top of a module about its purpose, contact
|
||||
information for its programmer and any useful notes.
|
||||
|
||||
Include a comment by each non-trival function describing its arguments,
|
||||
purpose and any other notes.
|
||||
|
||||
Update the documentation in this directory
|
||||
|
||||
These guidelines are an ideal, no one manages to implement them all the
|
||||
time, straightforward working code is probably just as good.
|
||||
|
||||
* Debugging
|
||||
|
||||
Debugging kernel-mode code is tricky, these are some snippets
|
||||
|
||||
DbgPrint writes a message to the console using a printf style format
|
||||
string. The DPRINT macro (defined in internal/debug.h) expands to
|
||||
DbgPrint unless NDEBUG is defined, this is useful for having copious
|
||||
output from a module only when a problem is being debugging. DPRINT
|
||||
also prefixes the message with the file and line number to make it
|
||||
easier to see where output is coming from. DbgPrint can be used at any
|
||||
point including in interrupt handlers.
|
||||
|
||||
There are options in ntoskrnl/kd/kdebug.c for copying DbgPrint output
|
||||
to a serial device or bochs logging port (parallel support should also
|
||||
be added). This can be useful if a lot of output is being generated.
|
||||
|
||||
It should be possible to include support for debugging the kernel with
|
||||
gdb over a serial line. Bochs (a shareware CPU emulator) is also useful
|
||||
for debugging the kernel, I wrote some patches to allow capture of console
|
||||
output from within bochs to file and for debugging a kernel running
|
||||
under bochs with gdb. Contact me (welch@cwcom.net) if you're are
|
||||
interested.
|
||||
|
||||
If CPU reports an exception not handled by the kernel (any page fault
|
||||
not part of virtual memory support or any other exception) the kernel
|
||||
will display output like this and halt
|
||||
|
||||
General Protection Fault Exception: 13(0)
|
||||
CS:EIP xxxxxxxx:xxxxxxx
|
||||
DS xxxx ES xxxx FS xxxx GS xxxxx
|
||||
EAX: xxxx EBX: xxxx
|
||||
....
|
||||
EDI: xxxx EFLAGS: xxxx ESP: xxxx
|
||||
cr2: xxxx
|
||||
Stack: xxxx xxxx xxxx ...
|
||||
....
|
||||
Frames: xxxx xxxx xxxx ...
|
||||
....
|
||||
|
||||
The fault type will usually be either 'General Protection' or
|
||||
'Page Fault', see your Intel manual for the more exotic types. The
|
||||
'EIP' number is the address of the faulting instruction. If the 'CS'
|
||||
number is 0x20 then the exception occured in kernel mode, if it is 0x11
|
||||
then the exception occurred in user mode. 'cr2' is the address that the
|
||||
faulting instruction was trying to access, if the exception was a page
|
||||
fault. The number printed after 'Frames' are any addresses on the stack
|
||||
that look like function addresses.
|
||||
|
||||
|
||||
If the kernel detects a serious problem that it will bug check, displaying
|
||||
output like this
|
||||
|
||||
Bug detected (code x, param x x x x)
|
||||
Frames: xxx xxxx xxxx
|
||||
....
|
||||
|
||||
Again the numbers printed after 'Frames' are any addresses on the stack
|
||||
that look like function addresss. Usually the kernel will also print a
|
||||
message describing the problem in more detail, the bug check code isn't
|
||||
very useful at the moment.
|
||||
|
||||
* Contacts
|
||||
|
||||
There is a mailing list for kernel development,
|
||||
|
||||
ros-kernel@reactos.com
|
||||
|
||||
The main developers use a cvs account to coordinate changes, ask
|
||||
rex (rex@lvcablemodem.com) for an account if you are going to be adding
|
||||
a lot of code. Smaller patches can go to the mailing list or to the
|
||||
relevant developer (usually the comment at the top of a module will have
|
||||
an email address). Regular snapshots are made available for download,
|
||||
see the mailing list for announcements.
|
||||
|
||||
* Legal stuff
|
||||
|
||||
The ReactOS project is GPL'ed, please make sure any code submitted is
|
||||
compatible with this.
|
||||
|
||||
The NT4 ddk license agreement allows its usage for developing nt drivers
|
||||
only. Legally therefore it can not be used to develop ReactOS, neither the
|
||||
documentation or the sample code. I'm not a lawyer, but I doubt the
|
||||
effiacy of 'shrinkwrap licenses' particularly on freely downloadable
|
||||
software. The only precendent I know of, in a Scottish court, didn't
|
||||
upload this type of license.
|
||||
|
||||
Also the 'fair use' section of copyright law allows the 'quoting' of small
|
||||
sections from copyrighted documents, e.g. Windows API or DDK documentation
|
6
reactos/doc/INDEX
Normal file
6
reactos/doc/INDEX
Normal file
@@ -0,0 +1,6 @@
|
||||
HACKING: Some notes for adding code to ReactOS
|
||||
DIRS: Explanation of directory layout
|
||||
INTERNALS: Some notes on kernel internals
|
||||
TODO: Bugs and omissions, big and little things that need to be done
|
||||
NOTES: Unsorted material, some of it is redundant
|
||||
BUGLIST: Known bugs, please update when you find one
|
43
reactos/doc/INTERNALS
Normal file
43
reactos/doc/INTERNALS
Normal file
@@ -0,0 +1,43 @@
|
||||
A collection of articles on kernel internals, please add to this
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
IRQ level
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
IRQ level (IRQL) is a per-processor state in ReactOS used to coordinate
|
||||
execution between ISRs and between threads. There are several levels
|
||||
|
||||
PASSIVE_LEVEL, APC_LEVEL: The normal level for user mode and most
|
||||
kernel mode code. At the moment APC_LEVEL is unused.
|
||||
|
||||
DISPATCH_LEVEL: At this level all irqs are still allowed but thread
|
||||
rescheduling on the current processor is disabled. This is used by
|
||||
the spinlock synchronization primitive to implement its uniprocessor
|
||||
semantics (multiprocessor is more complex). It is also used for some
|
||||
other forms of synchronization, DPCs for example. Many APIs are
|
||||
unavailable at this IRQL, usually those that might have to wait. It
|
||||
is recommended that you don't spend too much time at this IRQL
|
||||
otherwise system responsiveness will be reduced.
|
||||
|
||||
> DISPATCH_LEVEL: Each irq is assigned a priority (which will be
|
||||
greater than DISPATCH_LEVEL). At an irq's priority level that irq,
|
||||
lower priority irqs and thread rescheduling are disabled. Higher
|
||||
priority irqs can still run. Very few APIs are available at IRQLs
|
||||
greater than DISPATCH_LEVEL.
|
||||
|
||||
HIGH_LEVEL: All irqs are disabled.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
DPCs
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
It is a design goal not to spend too much time in ISRs, for this reason
|
||||
ISRs should postpone most processing till it can run at a lower IRQL. The
|
||||
mechanism for this is a Delayed Procedure Call (DPC). When a DPC object is
|
||||
created, it is associated with a function. The DPC object can then be inserted
|
||||
in the DPC queue from an ISR. If the IRQL on return from the ISR is less than
|
||||
DISPATCH_LEVEL the DPC queue will be drained, otherwise this will happen when
|
||||
the IRQL level drops below DISPATCH_LEVEL or the processor becomes idle. When
|
||||
the DPC queue is drained each DPC object is removed and the associated
|
||||
function is called at DISPATCH_LEVEL. A DPC object can only be inserted once,
|
||||
further insertions before it is removed will have no effect.
|
36
reactos/doc/apc
Normal file
36
reactos/doc/apc
Normal file
@@ -0,0 +1,36 @@
|
||||
APC
|
||||
|
||||
Asynchronous procedure call
|
||||
|
||||
An APC is a Kernel-defined control object representing a procedure
|
||||
that is called asynchronously. APCs are thread-context dependent; that
|
||||
is, they are queued to a particular thread for execution.
|
||||
|
||||
There are three different kinds of APCs in NT:
|
||||
|
||||
User APCs are used by certain asynchronous NT system services to allow
|
||||
user-mode applications or protected subsystems to synchronize the
|
||||
execution of a thread with the completion of an operation or the
|
||||
occurrence of an event such as a timers expiration. User APCs are, by
|
||||
default, disabled. That is, they are queued to the user-mode thread,
|
||||
but they are not executed except at well-defined points in the
|
||||
program. Specifically, they can only be executed when an application
|
||||
or protected subsystem has called a wait service and has enabled
|
||||
alerts to occur, or if it has called the test-alert service.
|
||||
|
||||
Kernel APCs are normal kernel-mode APCs. They are much like a normal
|
||||
user APC except that they are executable by default. That is, they are
|
||||
enabled except when the thread is already executing a Kernel APC.
|
||||
(Note that a special Kernel APC always preempts these.)
|
||||
|
||||
Special Kernel APCs cannot be blocked except by running at a raised
|
||||
IRQL. They are executed at APC_LEVEL IRQL (see IDT), in kernel mode.
|
||||
These types of APCs are used by the system to force a thread to
|
||||
execute a procedure in the threads context. An example of this is I/O
|
||||
completion: the I/O Manager needs to get back into the context of the
|
||||
original requestor of the I/O operation so that it can copy buffers,
|
||||
and so forth. In order to do this, the I/O Manager must be able to
|
||||
access the virtual address space of the thread/process, and the most
|
||||
efficient way to complete the operation is to be in the calling
|
||||
threads context.
|
||||
|
696
reactos/doc/notes
Normal file
696
reactos/doc/notes
Normal file
@@ -0,0 +1,696 @@
|
||||
*** This file contains messages I've culled off the net as well
|
||||
as previous discussions all of which have useful info on fixes
|
||||
that need to be added to ReactOS. messages are between five
|
||||
dashes on a line by themselves. If you implement the fix
|
||||
reffered to in a message, feel free to delete it from the file.
|
||||
Rex ***
|
||||
-----
|
||||
Subject: [ros-kernel] Inside the Boot Process
|
||||
Date: Mon, 22 Mar 1999 22:05:47 +0100
|
||||
From: Emanuele Aliberti <ea@iol.it>
|
||||
|
||||
For those working on the boot loader: in WinNt Magazine november 1998
|
||||
issue (http://www.winntmag.com/) there is a detailed description, by
|
||||
Mark Russinovich, of the r<>le the MBR, NTLDR, boot.ini, ntdetect.com...
|
||||
play in the boot process ("Inside the Boot Process, Part 1").
|
||||
-----
|
||||
Yes with DPCs, KeDrainDpcQueue should go to HIGH_LEVEL because
|
||||
it needs to synchronize with KeInsertDpcQueue. Also the idle thread
|
||||
should run at DISPATCH_LEVEL and regularly drain the dpc queue, that
|
||||
way if an irq happens and the dpc can't be executed immediately it
|
||||
will be executed as soon as the processor is idle rather than
|
||||
waiting for the next timer tick
|
||||
-----
|
||||
About the console driver, I think it might be quite useful to have a simple
|
||||
way for apps to print to the screen for debugging. But when the kernel is more
|
||||
stable, console handling should be moved to user level because console printing
|
||||
needs to know about windows and so on which can only be done at user level.
|
||||
-----
|
||||
Subject: Re: IMSAMP-how to avoid rebooting?
|
||||
Date: 9 Nov 1998 00:40:32 -0000
|
||||
From: Charles Bryant <n51190709.ch@chch.demon.co.uk>
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1, 2 , 3 , 4
|
||||
|
||||
In article <un264wzle.fsf@xxx.yyy.zzz>, David C. <qqqq@xxx.yyy.zzz> wrote:
|
||||
>The reason it won't unload when something is bound to it is the same
|
||||
>reason you can't unload any other driver that has an open client. If
|
||||
>you install any driver, and have a user program (or another driver) open
|
||||
>a handle to it, and then give the "net stop" command to unload it,
|
||||
>you'll find that the unload will be delayed until the user program
|
||||
>closes its handle.
|
||||
|
||||
When developing a driver I found this to be a considerable nuisance.
|
||||
Frequently a bug would leave an IRP stuck in the driver and I
|
||||
couldn't unload and reload a fixed version. While reading NTDDK.H I
|
||||
found a suspicious constant and discovered that the Flags field in
|
||||
the device (the one which you OR in DO_BUFFERED_IO or DO_DIRECT_IO)
|
||||
has a bit called DO_UNLOAD_PENDING. By experiment I confirmed that
|
||||
this bit is set when you do 'net stop', so a driver can check it
|
||||
periodically (e.g. from a timer DPC every ten seconds) and cancel all
|
||||
queued IRPs if it is found to be set.
|
||||
|
||||
Since this is not documented anywhere that I can find, it might be
|
||||
unwise to rely on it for production code, but it is very useful for
|
||||
debugging. Maybe someone with internals knowledge can comment on the
|
||||
reliability of it.
|
||||
-----
|
||||
Subject: Re: Kernel bugs
|
||||
Date: Fri, 23 Oct 1998 12:08:36 -0700
|
||||
From: rex <rex@lvcablemodem.com>
|
||||
To: Jason Filby <jasonfilby@yahoo.com>
|
||||
References: 1
|
||||
|
||||
Jason Filby wrote:
|
||||
|
||||
> Hi,
|
||||
>
|
||||
> Ok -- here's most of what I get when I press a key:
|
||||
>
|
||||
> Page fault detected at address 1fd4 with eip c042f794
|
||||
> Recursive page fault detected
|
||||
> Exception 14(2)
|
||||
> CS:EIP 20:c042f794
|
||||
>
|
||||
> Rex -- do you know of anyway to find out which function in what file
|
||||
> is causing the exception? I know that for problems in the kernel, you
|
||||
> just look in the ntoskrnl\kernel.sym file and find the EIP value which
|
||||
> matches the one given in the exception debug text. But what about
|
||||
> modules? How can we track exceptions that occur in functions in modules?
|
||||
>
|
||||
|
||||
I know this is a little belated, but I thought I'd take astab at answering
|
||||
this anyway. add an option to the
|
||||
makefile for the module to generate a listing file with
|
||||
symbol information. Then, on a boot test, note the
|
||||
address that the module is loaded at, and subtract
|
||||
this from the EIP value. add any offset used in the
|
||||
module link specification (I dont think there currently
|
||||
is one), and look for the last symbol with a lower
|
||||
address offset.
|
||||
|
||||
Brian, I have an idea on how to make this exception
|
||||
dump information a little more useful. We should
|
||||
have the load information for the load modules
|
||||
in memory somewhere. Perhaps the exception
|
||||
dump could check offending addresses to see if
|
||||
they lie in the kernel or in a module, and if they
|
||||
lie in a module the proper offset could be subtracted
|
||||
and this number could be displayed seperately. If
|
||||
I get a chance today, I'll make this change and send
|
||||
it to ya.
|
||||
|
||||
Rex.
|
||||
-----
|
||||
Subject: [ros-kernel] Pet peeve of the week
|
||||
Resent-Date: Sun, 25 Oct 1998 11:57:40 -0600
|
||||
Resent-From: ros-kernel@sid-dis.com
|
||||
Date: Sun, 25 Oct 1998 09:53:48 -0800
|
||||
From: rex <rex@lvcablemodem.com>
|
||||
Reply-To: <ros-kernel@sid-dis.com>
|
||||
To: ReactOS Kernel Forum <ros-kernel@sid-dis.com>
|
||||
|
||||
Hi all,
|
||||
|
||||
I guess it's about time to start another mailstorm
|
||||
on the list. :)
|
||||
|
||||
I have a suggestion for a change to the kernel.
|
||||
It not a very big change, and I hope everyone
|
||||
will agree that it makes sense.
|
||||
|
||||
There is a structure used in many places in the
|
||||
kernel called LARGE_INTEGER. the is also
|
||||
a version called ULARGE_INTEGER, but it
|
||||
is not used at all as far as I can tell. this structure
|
||||
is equivalent to a long long int. You can literally
|
||||
cast a pointer to a LARGE_INTEGER to a
|
||||
long long int and all manipulation will work
|
||||
seemlessly. My suggestion is that we replace the
|
||||
use of this structure with long long ints. Even
|
||||
microsoft, in their infinite wisdom, has made this
|
||||
suggestion in the DDK documentation. If you're
|
||||
wondering where, look at the RTL functions
|
||||
that manipulate LARGE_INTEGER structs.
|
||||
|
||||
Replacing LI's with long long ints will work
|
||||
because they are binary compatable. All software
|
||||
compiled to use LI's will manipulate long long ints
|
||||
correctly and vice versa. There is one problem
|
||||
with this suggestion: the LARGE_INTEGER type
|
||||
is a structure containing 2 members. Any code
|
||||
that accesses the structure by members will break.
|
||||
I think the kernel side impact is minimal, and is
|
||||
worth the change. However, the structure is used
|
||||
in several of the Win32 API functions, and needs
|
||||
to remain there. I think we build a conditionally
|
||||
compiled version of the LARGE_INTEGER type.
|
||||
In kernel mode code (the kernel proper and drivers)
|
||||
the LARGE INTEGER will be the following:
|
||||
|
||||
typedef long long int LARGE_INTEGER,
|
||||
*PLARGE_INTEGER;
|
||||
typedef unsigned long long int ULARGE_INTEGER,
|
||||
*PULARGE_INTEGER;
|
||||
|
||||
and in user mode code it will expand out to the
|
||||
current definition (which by the way, is not
|
||||
strictly correct, but can't be because it uses a
|
||||
MS compiler extension).
|
||||
|
||||
Brian, I would be willing to make the conversion
|
||||
to those kernel modules that needed it, and of
|
||||
course to the IDE driver if we want to go forward
|
||||
with the change.
|
||||
|
||||
Lastly, I'll mention what made me consider this.
|
||||
I was fixing the timer routines, and two of the
|
||||
three problems turned out to be related to LI
|
||||
conversion problems.
|
||||
|
||||
Rex.
|
||||
-----
|
||||
Subject: Re: [ros-kernel] Pet peeve of the week
|
||||
Date: Thu, 29 Oct 1998 19:10:37 +0100
|
||||
From: Boudewijn <ariadne@xs4all.nl>
|
||||
To: rex@lvcablemodem.com
|
||||
References: 1
|
||||
|
||||
Hai Rex
|
||||
|
||||
I think it is a good idea to wrap a makro around the member access
|
||||
to large integers.
|
||||
I haven't tested this, but do you think this is a good sugestion ?
|
||||
|
||||
#ifdef COMPILER_LARGE_INTEGERS
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( ( LargeInteger >>
|
||||
32) )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) ( (LargeInteger &
|
||||
0xFFFFFFFF) )
|
||||
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
|
||||
LargeInteger |= ( ((LARGE_INTEGER)Signed_Long) << 32 ) )
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
|
||||
LargeInteger |= Unsigned_Long )
|
||||
#else
|
||||
#define GET_LARGE_INTEGER_HIGH_PART(LargeInteger) ( (
|
||||
LargeInteger.HighPart) )
|
||||
#define GET_LARGE_INTEGER_LOW_PART(LargeInteger) (
|
||||
(LargeInteger.LowPart) )
|
||||
#define SET_LARGE_INTEGER_HIGH_PART(LargeInteger,Signed_Long) (
|
||||
LargeInteger.HighPart= Signed_Long )
|
||||
#define SET_LARGE_INTEGER_LOW_PART(LargeInteger,Unsigned_Long) (
|
||||
LargeInteger.LowPart = Unsigned_Long )
|
||||
#endif
|
||||
|
||||
Boudewijn
|
||||
-----
|
||||
Subject: Re: Question on "Sending buffers on the stack to asynchronous DeviceIoControl with buffered I/O"
|
||||
Date: Mon, 16 Nov 1998 11:24:57 -0800
|
||||
From: "-Paul" <paulsan@microsoftSPAM.com>
|
||||
Organization: Microsoft Corp.
|
||||
Newsgroups: microsoft.public.win32.programmer.kernel, comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
Radu, I post the following information occassionally for questions such as
|
||||
yours. I hope it helps.
|
||||
|
||||
-Paul
|
||||
|
||||
Here is an explanation of buffers and DeviceIoControl.
|
||||
|
||||
First, here are the parameters,
|
||||
|
||||
BOOL DeviceIoControl(
|
||||
HANDLE hDevice, // handle to device of interest
|
||||
DWORD dwIoControlCode, // control code of operation to perform
|
||||
LPVOID lpInBuffer, // pointer to buffer to supply input data
|
||||
DWORD nInBufferSize, // size of input buffer
|
||||
LPVOID lpOutBuffer, // pointer to buffer to receive output data
|
||||
DWORD nOutBufferSize, // size of output buffer
|
||||
LPDWORD lpBytesReturned, // pointer to variable to receive output byte
|
||||
count
|
||||
LPOVERLAPPED lpOverlapped // pointer to overlapped structure for
|
||||
asynchronous operation
|
||||
);
|
||||
|
||||
METHOD_BUFFERED
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver
|
||||
lpOutBuffer - optional, contains data that is read from the driver after
|
||||
the call has completed
|
||||
|
||||
lpInBuffer and lpOutBuffer can be two buffers or a single shared buffer.
|
||||
If a shared buffer, lpInBuffer is overwritten by lpOutBuffer.
|
||||
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
examines nInBufferSize and nOutBufferSize. Allocates memory from non-paged
|
||||
pool and puts the address of this pool in Irp->AssociatedIrp.SystemBuffer.
|
||||
The size of this buffer is equal to the size of the larger of the two
|
||||
bufferes. This buffer is accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
calls your driver
|
||||
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
you have one buffer, Irp->AssociatedIrp.SystemBuffer. You read input data
|
||||
from this buffer and you write output data to the same buffer, overwriting
|
||||
the input data.
|
||||
|
||||
Before calling IoCompleteRequest, you must
|
||||
- set IoStatus.Status to an approriate NtStatus
|
||||
- if IoStatus.Status == STATUS_SUCCESS
|
||||
set IoStatus.Information to the
|
||||
number of bytes you want copied
|
||||
from the SystemBuffer back into
|
||||
lpOutBuffer.
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
looks at IoStatus block, if IoStatus.Status = STATUS_SUCCESS, copies the
|
||||
number of bytes specified by IoStatus.Information from
|
||||
Irp->AssociatedIrp.SystemBuffer into lpOutBuffer
|
||||
completes the request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_IN_DIRECT
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver. This
|
||||
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
|
||||
confusion, mentally rename this buffer to lpControlBuffer. This is
|
||||
typically a small, optional buffer that might contain a control structure
|
||||
with useful information for the device driver. This buffer is smal and is
|
||||
double buffered.
|
||||
|
||||
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is read by
|
||||
the driver. To avoid confusion, mentally rename this buffer to
|
||||
lpDataTransferBuffer. This is physically the same buffer that the device
|
||||
driver will read from. There is no double buffering. Technically, this
|
||||
buffer is still optional, but since you are using this buffering method,
|
||||
what would be the point???
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
If lpInBuffer exists, allocates memory from non-paged pool and puts the
|
||||
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
|
||||
accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
So far this is completely identical to METHOD_BUFFERED. Most likely
|
||||
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
|
||||
|
||||
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
|
||||
allocated. lpOutBuffer is probed and locked into memory. Then, the user
|
||||
buffer virtual addresses are checked to be sure they are readable in the
|
||||
caller's access mode.
|
||||
|
||||
The MDL is address is stored in Irp->MdlAddress.
|
||||
Your driver is called.
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
The device driver can read the copy of lpOutBuffer via
|
||||
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
|
||||
this buffer is lost. The I/O Manager does not copy any data back to the
|
||||
user-mode buffers as it did in the completion routine for METHOD_BUFFERED.
|
||||
Art Baker's book is wrong in this respect (page 168, "data going from the
|
||||
driver back to the caller is passed through an intermediate system-space
|
||||
buffer" and page 177, "When the IOCTL IRP is completed, the contents of the
|
||||
system buffer will be copied back into the callers original output buffer".
|
||||
|
||||
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
|
||||
The driver uses whatever Mdl API's to read the buffer. Usually, this
|
||||
buffer is to be written to some mass storage media or some similar
|
||||
operation. Since this is a large data transfer, assume a completion
|
||||
routine is required.
|
||||
|
||||
mark the Irp pending
|
||||
queue it
|
||||
return status pending
|
||||
|
||||
|
||||
|
||||
|
||||
Device Driver Completion Routine perspective
|
||||
|
||||
standard completion routine operations
|
||||
set IoStatus.Status to an approriate NtStatus
|
||||
IoStatus.Information is not needed
|
||||
completete the request
|
||||
|
||||
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
standard I/O Manager completion routine operations
|
||||
unmap the pages
|
||||
deallocate the Mdl
|
||||
complete the request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_OUT_DIRECT
|
||||
|
||||
user-mode perspective
|
||||
|
||||
lpInBuffer - optional, contains data that is written to the driver. This
|
||||
buffer is used in the exact same fashion as METHOD_BUFFERED. To avoid
|
||||
confusion, mentally rename this buffer to lpControlBuffer. This is
|
||||
typically a small, optional buffer that might contain a control structure
|
||||
with useful information for the device driver. This buffer is smal and is
|
||||
double buffered.
|
||||
|
||||
lpOutBuffer - NOT OPTIONAL, This LARGE buffer contains data that is written
|
||||
by the driver and read by the wer-mode application when the request is
|
||||
completed. To avoid confusion, mentally rename this buffer to
|
||||
lpDataTransferBuffer. This is physically the same buffer that the device
|
||||
driver will write to. There is no double buffering. Technically, this
|
||||
buffer is still optional, but since you are using this buffering method,
|
||||
what would be the point???
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
If lpInBuffer exists, allocates memory from non-paged pool and puts the
|
||||
address of this pool in Irp->AssociatedIrp.SystemBuffer. This buffer is
|
||||
accessible at any IRQL.
|
||||
|
||||
copies nInBufferSize to irpSp->Parameters.DeviceIoControl.InputBufferLength
|
||||
copies nOutBufferSize to
|
||||
irpSp->Parameters.DeviceIoControl.OutputBufferLength
|
||||
copies contents of lpInBuffer to SystemBuffer allocated above
|
||||
So far this is completely identical to METHOD_BUFFERED. Most likely
|
||||
lpInBuffer (mentally renamed to lpControlBuffer) is very small in size.
|
||||
|
||||
For lpOutBuffer (mentally renamed to lpDataTransferBuffer), an MDL is
|
||||
allocated. lpOutBuffer is probed and locked into memory. Then the user
|
||||
buffer's addresses are checked to make sure the caller could write to them
|
||||
in the caller's access mode.
|
||||
|
||||
The MDL is address is stored in Irp->MdlAddress.
|
||||
Your driver is called.
|
||||
|
||||
|
||||
Device Driver perspective
|
||||
|
||||
The device driver can read the copy of lpOutBuffer via
|
||||
Irp->AssociatedIrp.SystemBuffer. Anything written by the device driver to
|
||||
this buffer is lost.
|
||||
|
||||
The device driver accesses the Win32 buffer directly via Irp->MdlAddress.
|
||||
The driver uses whatever Mdl API's to write data to the buffer. Usually,
|
||||
this buffer is to be read from some mass storage media or some similar
|
||||
operation. Since this is a large data transfer, assume a completion
|
||||
routine is required.
|
||||
|
||||
mark the Irp pending
|
||||
queue it
|
||||
return status pending
|
||||
|
||||
|
||||
|
||||
|
||||
Device Driver Completion Routine perspective
|
||||
|
||||
standard completion routine operations
|
||||
set IoStatus.Status to an approriate NtStatus
|
||||
IoStatus.Information is not needed
|
||||
completete the request
|
||||
|
||||
|
||||
|
||||
|
||||
I/O Manager Completion Routine perspective
|
||||
|
||||
standard I/O Manager completion routine operations
|
||||
unmap the pages
|
||||
deallocate the Mdl
|
||||
complete the request
|
||||
|
||||
|
||||
|
||||
|
||||
METHOD_NEITHER
|
||||
|
||||
I/O Manager perspective
|
||||
|
||||
Irp->UserBuffer = lpOutputBuffer;
|
||||
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer = lpInputBuffer;
|
||||
|
||||
No comments here. Don't use METHOD_DIRECT unless you know what you are
|
||||
doing. Simple rule.
|
||||
|
||||
If your IOCtl involves no data transfer buffers, then METHOD_NEITHER is the
|
||||
fastest path through the I/O Manager that involves an Irp.
|
||||
|
||||
|
||||
|
||||
|
||||
Final Comment
|
||||
|
||||
Don't touch Irp->UserBuffer. This is a bookmark for the I/O Manager. Two
|
||||
major problems can occur. 1 - page fault at high IRQL, or 2 - you write
|
||||
something to Irp->UserBuffer and the I/O Manager overwrites you in its
|
||||
completion routine. File systems access Irp->UserBuffer, but FSD writers
|
||||
know all of the above and know when it is safe to touch Irp->UserBuffer.
|
||||
|
||||
|
||||
|
||||
Radu Woinaroski wrote in message <364F8F6E.2434B010@scitec.com.au>...
|
||||
>Hello,
|
||||
>
|
||||
>I have a kernel-mode device driver that accepts a number of IoControl
|
||||
>commands that use buffered data transfer (METHOD_BUFFERED).
|
||||
>
|
||||
>A user mode API provides a higher level access then the DeviceIoControl
|
||||
>function.
|
||||
>
|
||||
>The function is implemented like that
|
||||
>
|
||||
>BOOL
|
||||
Something(
|
||||
> HANDLE hDevice ,
|
||||
> int param1,
|
||||
> int param2,
|
||||
> DWORD * pReturn,
|
||||
> LPOVERLAPPED pOverlapped)
|
||||
>{
|
||||
> // here a data buffer on the stack sent to asynchronous DeviceIoControl
|
||||
>call
|
||||
> int aDataIn[2];
|
||||
> aDataIn[0] = param1;
|
||||
> aDataIn[1] = param2;
|
||||
>
|
||||
> return DeviceIoControl(
|
||||
> hDevice,
|
||||
> DO_SOMETHING_IO,
|
||||
> aDataIn,
|
||||
> sizeof(int)*2,
|
||||
> pReturn,
|
||||
> sizeof(DWORD),
|
||||
> pOverlapped);
|
||||
>}
|
||||
>
|
||||
>The aDataIn buffer will not exist after DeviceIoControl returns (and
|
||||
>when the I/O operation terminates). I know that for buffered IO the
|
||||
>input data buffer is copyed by de IOManager to a nonpaged-pool area
|
||||
>before passing the request to driver dispatch routine (DeviceControl).
|
||||
>At the point of calling the dispatch routine (DeviceControl) the driver
|
||||
>runs in the context of the calling thread so DeviceIoControl hasn't
|
||||
>returned yet (?? or so I think) so aDataI
|
||||
n will still be valid at the
|
||||
>time IOManager copyes it to its buffer. So, this apears to work ok (at
|
||||
>least in my opinion).
|
||||
>
|
||||
>Does I/O Manager use the Input buffer from the call to the Win32
|
||||
>DeviceIoControl any where else after the first copy ?
|
||||
>
|
||||
>Is there any reason why this approach (passing a buffer on the stack to
|
||||
>a asynchronous DeviceIoControl that uses buffered I/O) wouldn't work ?
|
||||
>
|
||||
>Allocating buffers from heap and deleting them on IO completion while
|
||||
>managing asynchronous IO seems too much work ;-) .
|
||||
>
|
||||
>Thanks in advance for your opinions
|
||||
>Radu W.
|
||||
>
|
||||
>--
|
||||
>Radu Woinaroski
|
||||
>Scitec
|
||||
>Sydney, Australia
|
||||
>Radu.Woinaroski@scitec.com.au
|
||||
-----
|
||||
Subject: Re: PCI ISR problem
|
||||
Date: Fri, 20 Nov 1998 18:04:48 GMT
|
||||
From: jeh@cmkrnl.com (Jamie Hanrahan)
|
||||
Organization: Kernel Mode Systems, San Diego, CA
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
On Thu, 19 Nov 1998 15:46:13 -0600, Eric Gardiner
|
||||
<eric.gardiner@natinst.com> wrote:
|
||||
|
||||
>I'm having problems with NT4 not hooking the interrupt line indicated by
|
||||
>a PCI device. Here's what I'm doing:
|
||||
>
|
||||
>1) Enumerating the PCI buses on the system (using HalGetBusData) until
|
||||
>I find my device.
|
||||
>2) Once my device is found, I read the "Interrupt Line Register" in the
|
||||
>device's PCI config space to determine what interrupt level to pass to
|
||||
>HalGetInterruptVector.
|
||||
|
||||
Whups! No. Call HalAssignSlotResources and look at the returned
|
||||
CM_RESOURCE_LIST to find the vector, level, port addresses, etc., for
|
||||
your device. (Then pass the returned CM_RESOURCE_LIST to ExFreePool.)
|
||||
|
||||
|
||||
See Knowledge Base article Q152044.
|
||||
|
||||
--- Jamie Hanrahan, Kernel Mode Systems, San Diego CA (jeh@cmkrnl.com)
|
||||
Drivers, internals, networks, applications, and training for VMS and Windows NT
|
||||
NT kernel driver FAQ, links, and other information: http://www.cmkrnl.com/
|
||||
|
||||
Please post replies, followups, questions, etc., in news, not via e-mail.
|
||||
-----
|
||||
Subject: Re: IRP canceling
|
||||
Date: Mon, 23 Nov 1998 09:05:47 -0500
|
||||
From: Walter Oney <waltoney@oneysoft.com>
|
||||
Organization: Walter Oney Software
|
||||
Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode
|
||||
References: 1
|
||||
|
||||
Seol,Keun Seok wrote:
|
||||
> But, if the IRP was the CurrentIrp of the Device Object,
|
||||
> the Driver's Start I/O routine will try to process the IRP.
|
||||
> In the DDK help, the Start I/O routine MUST check the current IRP's
|
||||
> Cancel bit.
|
||||
> If set, Start I/O routine must just return.
|
||||
>
|
||||
> But I think that the IRP already completed should not be accessed.
|
||||
|
||||
You're absolutely right. I recommend the following code in a standard
|
||||
StartIo routine to avoid the problem you point out:
|
||||
|
||||
VOID StartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
KIRQL oldirql;
|
||||
IoAcquireCancelSpinLock(&oldirql);
|
||||
if (Irp != DeviceObject->CurrentIrp || Irp->Cancel)
|
||||
{
|
||||
IoReleaseCancelSpinLock(oldirql);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
IoSetCancelRoutine(Irp, NULL);
|
||||
IoReleaseCancelSpinLock(oldirql);
|
||||
}
|
||||
. . .
|
||||
}
|
||||
|
||||
This dovetails with a standard cancel routine:
|
||||
|
||||
VOID CancelRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
if (DeviceObject->CurrentIrp == Irp)
|
||||
{
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
IoStartNextPacket(DeviceObject, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,
|
||||
&Irp->Tail.Overlay.DeviceQueueEntry);
|
||||
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
||||
}
|
||||
Irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
You need to remember that the C language specification requires that
|
||||
evaluation of boolean operators short circuit when the result is known.
|
||||
So, if StartIo discovers that the Irp it got as an argument is not the
|
||||
same as CurrentIrp, it will not attempt to evaulate Irp->Cancel.
|
||||
|
||||
Now, as to why this works: StartIo gets called either by IoStartPacket
|
||||
or IoStartNextPacket. Each of them will grab the cancel spin lock and
|
||||
set CurrentIrp, then release the spin lock and call StartIo. If someone
|
||||
should sneak in on another CPU and cancel this very same IRP, your
|
||||
cancel routine will immediately release the spin lock and call
|
||||
IoStartNextPacket. One of two things will then happen. IoStartNextPacket
|
||||
may succeed in getting the cancel spin lock, whereupon it will nullify
|
||||
the CurrentIrp pointer. If another IRP is on the queue, it will remove
|
||||
it from the queue, set CurrentIrp to point to this *new* IRP, release
|
||||
the spin lock, and call StartIo. [You now have two instances of StartIo
|
||||
running on two different CPUs for two different IRPs, but it's not a
|
||||
problem because they won't be able to interfere with each other.]
|
||||
Meanwhile, your original instance of StartIo gets the cancel spin lock
|
||||
and sees that CurrentIrp is not equal to the IRP pointer it got as an
|
||||
argument, so it gives up.
|
||||
|
||||
The second way this could play out is that StartIo gets the cancel lock
|
||||
before IoStartNextPacket does. In this case, CurrentIrp is still
|
||||
pointing to the IRP that's in the process of being cancelled and that
|
||||
StartIo got as an argument. But this IRP hasn't been completed yet (the
|
||||
CPU that's running your cancel routine is spinning inside
|
||||
IoStartNextPacket and therefore hasn't gotten to calling
|
||||
IoCompleteRequest yet), so no-one will have been able to call IoFreeIrp
|
||||
to make your pointer invalid.
|
||||
|
||||
People may tell you that you should be using your own queues for IRPs so
|
||||
you can avoid bottlenecking the system on the global cancel spin lock.
|
||||
That's true enough, but doing it correctly with Plug and Play and Power
|
||||
management things in the way is gigantically complicated. There's a
|
||||
sample in the NT 5 beta-2 DDK called CANCEL that shows how to manage
|
||||
your own queue if you don't worry about PNP and POWER. I hear tell of an
|
||||
upcoming MSJ article by a Microsoft developer that may solve the
|
||||
complete problem.
|
||||
-----
|
||||
Subject: ANNOUNCE: ALINK v1.5
|
||||
Date: 16 Nov 1998 16:36:05 GMT
|
||||
From: anthony_w@my-dejanews.com
|
||||
Organization: Deja News - The Leader in Internet Discussion
|
||||
Newsgroups: comp.os.ms-windows.programmer.win32, comp.lang.asm.x86, comp.os.msdos.programmer
|
||||
|
||||
ALINK is a freeware linker, creating MSDOS COM and EXE files and Win32 PE EXE
|
||||
and DLL files from OMF format OBJ and LIB files, win32-COFF format OBJ files,
|
||||
and win32 RES files.
|
||||
|
||||
NEW for version 1.5:
|
||||
|
||||
Win32 COFF object file support.
|
||||
|
||||
Download it now from my home page.
|
||||
|
||||
Anthony
|
||||
--
|
||||
anthony_w@geocities.com
|
||||
http://www.geocities.com/SiliconValley/Network/4311/index.html
|
||||
|
||||
-----------== Posted via Deja News, The Discussion Network ==----------
|
||||
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
|
||||
-----
|
||||
|
59
reactos/doc/todo
Normal file
59
reactos/doc/todo
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
* Critical path tasks
|
||||
Test and debug Registry routines
|
||||
Finish multiple system service table support (HalRegisterServiceTable)
|
||||
Modify GENNTDLL to generate all needed system service tables
|
||||
|
||||
* These tasks would be nice
|
||||
Separate HAL into KM DLL
|
||||
|
||||
* Function groups totally or partially unimplemented
|
||||
|
||||
Dma functions (see hal/x86/dma.c)
|
||||
PCI interface functions (see hal/x86/bios32.c, hal/x86/pci.c)
|
||||
HalExamineMbr
|
||||
Locale support (see ex/locale.c)
|
||||
Shutdown support (see ex/power.c)
|
||||
Zw(Set/Get)SystemInformation (see ex/sysinfo.c)
|
||||
Adapter functions (see io/adapter.c)
|
||||
Io cancelation support (see io/cancel, et al)
|
||||
Directory change notification (see io/dir.c)
|
||||
Error logging (see io/errlog.c)
|
||||
Buffer flushing (see io/flush.c)
|
||||
Io completion ports (see io/iocomp.c)
|
||||
File locking (see io/lock.c)
|
||||
Mailslots (see io/mailslot.c)
|
||||
Named pipes (see io/npipe.c)
|
||||
Hardware resource management (see io/resource.c)
|
||||
File access checking (see io/share.c)
|
||||
APCs to user-mode (see ke/apc.c, ke/apchelp.asm)
|
||||
Exception support (see ke/catch.c)
|
||||
Mutex support (see ke/mutex.c)
|
||||
Semaphore support (see ke/sem.c)
|
||||
Timer support (see ke/timer.c)
|
||||
Properly calibrate delay loop (see ke/timer.c)
|
||||
Waiting for multiple objects (see ke/wait.c)
|
||||
Single linked lists (see rtl/slist.c)
|
||||
Sequenced lists (see rtl/seqlist.c)
|
||||
|
||||
* Verify implementation
|
||||
|
||||
Fast mutexes (see ex/fmutex.c)
|
||||
|
||||
* Major areas
|
||||
|
||||
Security support (see se/*.c)
|
||||
Registry support (see cm/*.c)
|
||||
Paging support
|
||||
File system cache support
|
||||
SCSI miniport driver
|
||||
Network support
|
||||
Video drivers
|
||||
USER and GDI modules
|
||||
|
||||
* Drivers
|
||||
NTFS, EXT2 filesystems
|
||||
Many others (use oem's where possible)
|
||||
|
||||
* For the future
|
||||
DOS, Win16, POSIX subsystems
|
4
reactos/drivers/dd/beep/.cvsignore
Normal file
4
reactos/drivers/dd/beep/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
290
reactos/drivers/dd/beep/beep.c
Normal file
290
reactos/drivers/dd/beep/beep.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/* $Id: beep.c,v 1.4 1999/10/16 12:41:42 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/beep/beep.c
|
||||
* PURPOSE: BEEP device driver
|
||||
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
* UPDATE HISTORY:
|
||||
* 30/01/99 Created
|
||||
* 16/10/99 Minor fixes
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddbeep.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* TYEPEDEFS ***************************************************************/
|
||||
|
||||
typedef struct tagBEEP_DEVICE_EXTENSION
|
||||
{
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
KEVENT Event;
|
||||
BOOL BeepOn;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
|
||||
VOID BeepDPC (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeferredContext;
|
||||
|
||||
DPRINT ("BeepDPC() called!\n");
|
||||
HalMakeBeep (0);
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
KeSetEvent (&(DeviceExtension->Event), 0, TRUE);
|
||||
|
||||
DPRINT ("BeepDPC() finished!\n");
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
if (Stack->MajorFunction == IRP_MJ_CREATE)
|
||||
{
|
||||
DPRINT ("BeepCreate() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp,IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
switch (Stack->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CLOSE:
|
||||
DPRINT ("BeepClose() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
if (Stack->MajorFunction == IRP_MJ_CLEANUP)
|
||||
{
|
||||
DPRINT ("BeepCleanup() called!\n");
|
||||
Irp->IoStatus.Information = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
/*
|
||||
* FUNCTION: Handles user mode requests
|
||||
* ARGUMENTS:
|
||||
* DeviceObject = Device for request
|
||||
* Irp = I/O request packet describing request
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
PBEEP_SET_PARAMETERS pbsp;
|
||||
NTSTATUS status;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
DPRINT ("BeepDeviceControl() called!\n");
|
||||
if (Stack->Parameters.DeviceIoControl.IoControlCode == IOCTL_BEEP_SET)
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (Stack->Parameters.DeviceIoControl.InputBufferLength == sizeof(BEEP_SET_PARAMETERS))
|
||||
{
|
||||
pbsp = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if (pbsp->Frequency >= BEEP_FREQUENCY_MINIMUM &&
|
||||
pbsp->Frequency <= BEEP_FREQUENCY_MAXIMUM)
|
||||
{
|
||||
LARGE_INTEGER DueTime;
|
||||
|
||||
DueTime.QuadPart = 0;
|
||||
|
||||
/* do the beep!! */
|
||||
DPRINT ("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
|
||||
pbsp->Frequency, pbsp->Duration);
|
||||
|
||||
if (pbsp->Duration >= 0)
|
||||
{
|
||||
DueTime.QuadPart = (LONGLONG)pbsp->Duration * -10000;
|
||||
|
||||
KeSetTimer (&DeviceExtension->Timer,
|
||||
DueTime,
|
||||
&DeviceExtension->Dpc);
|
||||
|
||||
HalMakeBeep (pbsp->Frequency);
|
||||
DeviceExtension->BeepOn = TRUE;
|
||||
KeWaitForSingleObject (&(DeviceExtension->Event),
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
}
|
||||
else if (pbsp->Duration == (DWORD)-1)
|
||||
{
|
||||
if (DeviceExtension->BeepOn)
|
||||
{
|
||||
HalMakeBeep (0);
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
HalMakeBeep (pbsp->Frequency);
|
||||
DeviceExtension->BeepOn = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT ("Did the beep!\n");
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS BeepUnload(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
DPRINT ("BeepUnload() called!\n");
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
STDCALL NTSTATUS
|
||||
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Called by the system to initalize the driver
|
||||
* ARGUMENTS:
|
||||
* DriverObject = object describing this driver
|
||||
* RegistryPath = path to our configuration entries
|
||||
* RETURNS: Success or failure
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS ret;
|
||||
ANSI_STRING ansi_device_name;
|
||||
UNICODE_STRING device_name;
|
||||
ANSI_STRING asymlink_name;
|
||||
UNICODE_STRING symlink_name;
|
||||
|
||||
DbgPrint ("Beep Device Driver 0.0.2\n");
|
||||
|
||||
RtlInitAnsiString (&ansi_device_name, "\\Device\\Beep");
|
||||
RtlAnsiStringToUnicodeString (&device_name, &ansi_device_name, TRUE);
|
||||
ret = IoCreateDevice (DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&device_name,
|
||||
FILE_DEVICE_BEEP,
|
||||
0,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (ret!=STATUS_SUCCESS)
|
||||
{
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* prelininary */
|
||||
RtlInitAnsiString (&asymlink_name, "\\??\\Beep");
|
||||
RtlAnsiStringToUnicodeString (&symlink_name, &asymlink_name, TRUE);
|
||||
IoCreateSymbolicLink (&symlink_name, &device_name);
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
|
||||
DriverObject->DriverUnload = BeepUnload;
|
||||
|
||||
/* set up device extension */
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
DeviceExtension->BeepOn = FALSE;
|
||||
|
||||
KeInitializeDpc (&(DeviceExtension->Dpc),
|
||||
BeepDPC,
|
||||
DeviceExtension);
|
||||
KeInitializeTimer (&(DeviceExtension->Timer));
|
||||
KeInitializeEvent (&(DeviceExtension->Event),
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
39
reactos/drivers/dd/beep/beep.rc
Normal file
39
reactos/drivers/dd/beep/beep.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "PC Speaker Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.2\0"
|
||||
VALUE "InternalName", "beep\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "beep.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
71
reactos/drivers/dd/beep/makefile
Normal file
71
reactos/drivers/dd/beep/makefile
Normal file
@@ -0,0 +1,71 @@
|
||||
# $Id: makefile,v 1.6 1999/12/04 20:58:35 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET = beep
|
||||
OBJECTS = beep.o beep.coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
all: beep.sys
|
||||
|
||||
.PHONY: all
|
||||
|
||||
clean:
|
||||
- $(RM) beep.o
|
||||
- $(RM) beep.coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) beep.sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
|
||||
beep.sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp \
|
||||
$(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname beep.sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
include ../../../rules.mak
|
||||
|
4
reactos/drivers/dd/blue/.cvsignore
Normal file
4
reactos/drivers/dd/blue/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
634
reactos/drivers/dd/blue/blue.c
Normal file
634
reactos/drivers/dd/blue/blue.c
Normal file
@@ -0,0 +1,634 @@
|
||||
/* $Id: blue.c,v 1.19 2000/01/11 17:33:44 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/blue/blue.c
|
||||
* PURPOSE: Console (blue screen) device driver
|
||||
* PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
* UPDATE HISTORY:
|
||||
* ??? Created
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddblue.h>
|
||||
#include <string.h>
|
||||
#include <defines.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* DEFINITIONS ***************************************************************/
|
||||
|
||||
#define IDMAP_BASE 0xd0000000
|
||||
#define VIDMEM_BASE 0xb8000
|
||||
|
||||
#define CRTC_COMMAND ((PUCHAR)0x3d4)
|
||||
#define CRTC_DATA ((PUCHAR)0x3d5)
|
||||
|
||||
#define CRTC_COLUMNS 0x01
|
||||
#define CRTC_OVERFLOW 0x07
|
||||
#define CRTC_ROWS 0x12
|
||||
#define CRTC_SCANLINES 0x09
|
||||
#define CRTC_CURSORSTART 0x0a
|
||||
#define CRTC_CURSOREND 0x0b
|
||||
#define CRTC_CURSORPOSHI 0x0e
|
||||
#define CRTC_CURSORPOSLO 0x0f
|
||||
|
||||
#define ATTRC_WRITEREG ((PUCHAR)0x3c0)
|
||||
#define ATTRC_READREG ((PUCHAR)0x3c1)
|
||||
#define ATTRC_INPST1 ((PUCHAR)0x3da)
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
|
||||
/* NOTES ******************************************************************/
|
||||
/*
|
||||
* [[character][attribute]][[character][attribute]]....
|
||||
*/
|
||||
|
||||
|
||||
/* TYPEDEFS ***************************************************************/
|
||||
|
||||
typedef struct _DEVICE_EXTENSION
|
||||
{
|
||||
PBYTE VideoMemory; /* Pointer to video memory */
|
||||
DWORD CursorSize;
|
||||
BOOL CursorVisible;
|
||||
WORD CharAttribute;
|
||||
DWORD Mode;
|
||||
BYTE ScanLines; /* Height of a text line */
|
||||
WORD Rows; /* Number of rows */
|
||||
WORD Columns; /* Number of columns */
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
ScrCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
unsigned int offset;
|
||||
BYTE data, value;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
/* initialize device extension */
|
||||
|
||||
/* get pointer to video memory */
|
||||
/* FIXME : use MmMapIoSpace() */
|
||||
DeviceExtension->VideoMemory = (PBYTE)(IDMAP_BASE + VIDMEM_BASE);
|
||||
|
||||
/* disable interrupts */
|
||||
__asm__("cli\n\t");
|
||||
|
||||
/* get current output position */
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
|
||||
|
||||
/* switch blinking characters off */
|
||||
READ_PORT_UCHAR (ATTRC_INPST1);
|
||||
value = READ_PORT_UCHAR (ATTRC_WRITEREG);
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, 0x10);
|
||||
data = READ_PORT_UCHAR (ATTRC_READREG);
|
||||
data = data & ~0x08;
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, data);
|
||||
WRITE_PORT_UCHAR (ATTRC_WRITEREG, value);
|
||||
READ_PORT_UCHAR (ATTRC_INPST1);
|
||||
|
||||
/* read screen information from crt controller */
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_COLUMNS);
|
||||
DeviceExtension->Columns = READ_PORT_UCHAR (CRTC_DATA) + 1;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_ROWS);
|
||||
DeviceExtension->Rows = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_OVERFLOW);
|
||||
data = READ_PORT_UCHAR (CRTC_DATA);
|
||||
DeviceExtension->Rows |= (((data & 0x02) << 7) | ((data & 0x40) << 3));
|
||||
DeviceExtension->Rows++;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES);
|
||||
DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1;
|
||||
|
||||
/* enable interrupts */
|
||||
__asm__("sti\n\t");
|
||||
|
||||
/* calculate number of text rows */
|
||||
DeviceExtension->Rows =
|
||||
DeviceExtension->Rows / DeviceExtension->ScanLines;
|
||||
|
||||
DPRINT ("%d Columns %d Rows %d Scanlines\n",
|
||||
DeviceExtension->Columns,
|
||||
DeviceExtension->Rows,
|
||||
DeviceExtension->ScanLines);
|
||||
|
||||
DeviceExtension->CursorSize = 5; /* FIXME: value correct?? */
|
||||
DeviceExtension->CursorVisible = TRUE;
|
||||
|
||||
/* more initialization */
|
||||
DeviceExtension->CharAttribute = 0x17; /* light grey on blue */
|
||||
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
|
||||
ENABLE_WRAP_AT_EOL_OUTPUT;
|
||||
|
||||
/* show blinking cursor */
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
|
||||
data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA,
|
||||
data | ((DeviceExtension->ScanLines - 1) & 0x1F));
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
char *pch = Irp->UserBuffer;
|
||||
char *vidmem;
|
||||
int i, j, offset;
|
||||
int cursorx, cursory;
|
||||
int rows, columns;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
rows = DeviceExtension->Rows;
|
||||
columns = DeviceExtension->Columns;
|
||||
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA)<<8;
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset += READ_PORT_UCHAR (CRTC_DATA);
|
||||
|
||||
cursory = offset / columns;
|
||||
cursorx = offset % columns;
|
||||
|
||||
for (i = 0; i < stk->Parameters.Write.Length; i++, pch++)
|
||||
{
|
||||
switch (*pch)
|
||||
{
|
||||
case '\b':
|
||||
if (cursorx > 0)
|
||||
{
|
||||
cursorx--;
|
||||
}
|
||||
else if (cursory > 0)
|
||||
{
|
||||
cursorx = columns - 1;
|
||||
cursory--;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
offset = TAB_WIDTH - (cursorx % TAB_WIDTH);
|
||||
for (j = 0; j < offset; j++)
|
||||
{
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2)] = ' ';
|
||||
cursorx++;
|
||||
|
||||
if (cursorx >= columns)
|
||||
{
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2)] = *pch;
|
||||
vidmem[(cursorx * 2) + (cursory * columns * 2) + 1] = (char) DeviceExtension->CharAttribute;
|
||||
cursorx++;
|
||||
if (cursorx >= columns)
|
||||
{
|
||||
cursory++;
|
||||
cursorx = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (cursory >= rows)
|
||||
{
|
||||
unsigned short *LinePtr;
|
||||
|
||||
memcpy (vidmem,
|
||||
&vidmem[columns * 2],
|
||||
columns * (rows - 1) * 2);
|
||||
|
||||
LinePtr = (unsigned short *) &vidmem[columns * (rows - 1) * 2];
|
||||
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
LinePtr[j] = DeviceExtension->CharAttribute << 8;
|
||||
}
|
||||
cursory = rows - 1;
|
||||
for (j = 0; j < columns; j++)
|
||||
{
|
||||
vidmem[(j * 2) + (cursory * columns * 2)] = ' ';
|
||||
vidmem[(j * 2) + (cursory * columns * 2) + 1] = (char)DeviceExtension->CharAttribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the cursor position */
|
||||
offset = (cursory * columns) + cursorx;
|
||||
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset >>= 8;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrIoControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation (Irp);
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
switch (stk->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
int rows = DeviceExtension->Rows;
|
||||
int columns = DeviceExtension->Columns;
|
||||
unsigned int offset;
|
||||
|
||||
/* read cursor position from crtc */
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
offset = READ_PORT_UCHAR (CRTC_DATA);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
offset += (READ_PORT_UCHAR (CRTC_DATA) << 8);
|
||||
__asm__("sti\n\t");
|
||||
|
||||
pcsbi->dwSize.X = rows;
|
||||
pcsbi->dwSize.Y = columns;
|
||||
|
||||
pcsbi->dwCursorPosition.X = (SHORT)(offset % columns);
|
||||
pcsbi->dwCursorPosition.Y = (SHORT)(offset / columns);
|
||||
|
||||
pcsbi->wAttributes = DeviceExtension->CharAttribute;
|
||||
|
||||
pcsbi->srWindow.Left = 0;
|
||||
pcsbi->srWindow.Right = columns - 1;
|
||||
pcsbi->srWindow.Top = 0;
|
||||
pcsbi->srWindow.Bottom = rows - 1;
|
||||
|
||||
pcsbi->dwMaximumWindowSize.X = columns;
|
||||
pcsbi->dwMaximumWindowSize.Y = rows;
|
||||
|
||||
Irp->IoStatus.Information = sizeof (CONSOLE_SCREEN_BUFFER_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO:
|
||||
{
|
||||
PCONSOLE_SCREEN_BUFFER_INFO pcsbi = (PCONSOLE_SCREEN_BUFFER_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
unsigned int offset;
|
||||
|
||||
DeviceExtension->CharAttribute = pcsbi->wAttributes;
|
||||
|
||||
offset = (pcsbi->dwCursorPosition.Y * DeviceExtension->Columns) +
|
||||
pcsbi->dwCursorPosition.X;
|
||||
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSHI);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, offset>>8);
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_GET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
pcci->dwSize = DeviceExtension->CursorSize;
|
||||
pcci->bVisible = DeviceExtension->CursorVisible;
|
||||
|
||||
Irp->IoStatus.Information = sizeof (CONSOLE_CURSOR_INFO);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_CURSOR_INFO:
|
||||
{
|
||||
PCONSOLE_CURSOR_INFO pcci = (PCONSOLE_CURSOR_INFO)Irp->AssociatedIrp.SystemBuffer;
|
||||
BYTE data, value;
|
||||
DWORD size, height;
|
||||
|
||||
DeviceExtension->CursorSize = pcci->dwSize;
|
||||
DeviceExtension->CursorVisible = pcci->bVisible;
|
||||
height = DeviceExtension->ScanLines;
|
||||
data = (pcci->bVisible) ? 0x40 : 0x20;
|
||||
|
||||
size = (pcci->dwSize * height) / 100;
|
||||
if (size < 1)
|
||||
size = 1;
|
||||
|
||||
data |= (BYTE)(height - size);
|
||||
|
||||
__asm__("cli\n\t");
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, data);
|
||||
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
|
||||
value = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
|
||||
WRITE_PORT_UCHAR (CRTC_DATA, value | (height - 1));
|
||||
|
||||
__asm__("sti\n\t");
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_GET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
pcm->dwMode = DeviceExtension->Mode;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(CONSOLE_MODE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_MODE:
|
||||
{
|
||||
PCONSOLE_MODE pcm = (PCONSOLE_MODE)Irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
DeviceExtension->Mode = pcm->dwMode;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) Buf->wAttribute;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = Buf->nLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPWORD pAttr = (LPWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pAttr++)
|
||||
{
|
||||
(char) *pAttr = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE:
|
||||
{
|
||||
POUTPUT_ATTRIBUTE Buf = (POUTPUT_ATTRIBUTE)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPWORD pAttr = (LPWORD)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pAttr++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) *pAttr;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE:
|
||||
DeviceExtension->CharAttribute = (WORD)*(LPWORD)Irp->AssociatedIrp.SystemBuffer;
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
|
||||
case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2);
|
||||
|
||||
CHECKPOINT
|
||||
|
||||
for (dwCount = 0; dwCount < Buf->nLength; dwCount++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) Buf->cCharacter;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = Buf->nLength;
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2);
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pChar++)
|
||||
{
|
||||
*pChar = vidmem[offset + (dwCount * 2)];
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER:
|
||||
{
|
||||
POUTPUT_CHARACTER Buf = (POUTPUT_CHARACTER)Irp->AssociatedIrp.SystemBuffer;
|
||||
LPSTR pChar = (LPSTR)MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
char *vidmem;
|
||||
int offset;
|
||||
DWORD dwCount;
|
||||
|
||||
vidmem = DeviceExtension->VideoMemory;
|
||||
offset = (Buf->dwCoord.Y * DeviceExtension->Columns * 2) +
|
||||
(Buf->dwCoord.X * 2) + 1;
|
||||
|
||||
for (dwCount = 0; dwCount < stk->Parameters.Write.Length; dwCount++, pChar++)
|
||||
{
|
||||
vidmem[offset + (dwCount * 2)] = (char) *pChar;
|
||||
}
|
||||
|
||||
Buf->dwTransfered = dwCount;
|
||||
|
||||
Irp->IoStatus.Information = sizeof(OUTPUT_ATTRIBUTE);
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ScrDispatch (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS Status;
|
||||
|
||||
switch (stk->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Module entry point
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
ANSI_STRING adevice_name;
|
||||
UNICODE_STRING device_name;
|
||||
ANSI_STRING asymlink_name;
|
||||
UNICODE_STRING symlink_name;
|
||||
|
||||
DbgPrint ("Screen Driver 0.0.6\n");
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = ScrCreate;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = ScrDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = ScrWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL ] = ScrIoControl;
|
||||
|
||||
RtlInitAnsiString (&adevice_name, "\\Device\\BlueScreen");
|
||||
RtlAnsiStringToUnicodeString (&device_name, &adevice_name, TRUE);
|
||||
IoCreateDevice (DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&device_name,
|
||||
FILE_DEVICE_SCREEN,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
|
||||
RtlInitAnsiString (&asymlink_name, "\\??\\BlueScreen");
|
||||
RtlAnsiStringToUnicodeString (&symlink_name, &asymlink_name, TRUE);
|
||||
IoCreateSymbolicLink (&symlink_name, &device_name);
|
||||
|
||||
RtlFreeUnicodeString (&device_name);
|
||||
RtlFreeUnicodeString (&symlink_name);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* EOF */
|
39
reactos/drivers/dd/blue/blue.rc
Normal file
39
reactos/drivers/dd/blue/blue.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "HAL Console Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.6\0"
|
||||
VALUE "InternalName", "blue\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "blue.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
70
reactos/drivers/dd/blue/makefile
Normal file
70
reactos/drivers/dd/blue/makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
# $Id: makefile,v 1.10 1999/12/18 10:17:41 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET = blue
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET).o
|
||||
- $(RM) $(TARGET).coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) blue.sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
$(TARGET).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp $(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGET).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
|
||||
include ../../../rules.mak
|
2
reactos/drivers/dd/event/dirs
Normal file
2
reactos/drivers/dd/event/dirs
Normal file
@@ -0,0 +1,2 @@
|
||||
DIRS=exe \
|
||||
sys
|
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
168
reactos/drivers/dd/event/exe/eventtes.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
EventTest.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Simple console test app demonstrating how a Win32 app can share
|
||||
an event object with a kernel-mode driver. For more information
|
||||
on using Event Objects at the application level see the Win32 SDK.
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
User Mode
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// INCLUDES
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <winioctl.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "event.h"
|
||||
|
||||
|
||||
//
|
||||
// MAIN
|
||||
//
|
||||
void __cdecl
|
||||
main(
|
||||
int argc,
|
||||
char ** argv
|
||||
)
|
||||
{
|
||||
BOOL bStatus;
|
||||
HANDLE hDevice;
|
||||
ULONG ulReturnedLength;
|
||||
|
||||
SET_EVENT setEvent;
|
||||
FLOAT fDelay;
|
||||
|
||||
|
||||
if ( (argc < 2) || (argv[1] == NULL) ) {
|
||||
printf("event <delay>\n");
|
||||
printf("\twhere <delay> = time to delay the event signal in seconds.\n");
|
||||
exit(0);
|
||||
}
|
||||
sscanf( argv[1], "%f", &fDelay );
|
||||
|
||||
//
|
||||
// open the device
|
||||
//
|
||||
hDevice = CreateFile(
|
||||
"\\\\.\\EVENT", // lpFileName
|
||||
GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, // dwShareMode
|
||||
NULL, // lpSecurityAttributes
|
||||
OPEN_EXISTING, // dwCreationDistribution
|
||||
0, // dwFlagsAndAttributes
|
||||
NULL // hTemplateFile
|
||||
);
|
||||
|
||||
if (hDevice == INVALID_HANDLE_VALUE) {
|
||||
printf("CreateFile error = %d\n", GetLastError() );
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// set the event signal delay
|
||||
//
|
||||
setEvent.DueTime.QuadPart = -((LONGLONG)(fDelay * 10.0E6));// use relative time for this sample
|
||||
|
||||
|
||||
//
|
||||
// test the driver for bad event handles
|
||||
//
|
||||
setEvent.hEvent = NULL;
|
||||
bStatus = DeviceIoControl(
|
||||
hDevice, // Handle to device
|
||||
IOCTL_SET_EVENT, // IO Control code
|
||||
&setEvent, // Input Buffer to driver.
|
||||
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||
NULL, // Output Buffer from driver.
|
||||
0, // Length of output buffer in bytes.
|
||||
&ulReturnedLength, // Bytes placed in buffer.
|
||||
NULL // synchronous call
|
||||
);
|
||||
if ( !bStatus ) {
|
||||
printf("Bad handle TEST returned code %d.\n\n", GetLastError() );
|
||||
} else {
|
||||
printf("we should never get here\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
setEvent.hEvent = CreateEvent(
|
||||
NULL, // lpEventAttributes
|
||||
TRUE, // bManualReset
|
||||
FALSE, // bInitialState
|
||||
NULL // lpName
|
||||
);
|
||||
|
||||
|
||||
if ( !setEvent.hEvent ) {
|
||||
printf("CreateEvent error = %d\n", GetLastError() );
|
||||
} else {
|
||||
|
||||
printf("Event HANDLE = 0x%x\n", setEvent.hEvent );
|
||||
printf("Press any key to exit.\n");
|
||||
while( !_kbhit() ) {
|
||||
bStatus = DeviceIoControl(
|
||||
hDevice, // Handle to device
|
||||
IOCTL_SET_EVENT, // IO Control code
|
||||
&setEvent, // Input Buffer to driver.
|
||||
SIZEOF_SETEVENT, // Length of input buffer in bytes.
|
||||
NULL, // Output Buffer from driver.
|
||||
0, // Length of output buffer in bytes.
|
||||
&ulReturnedLength, // Bytes placed in buffer.
|
||||
NULL // synchronous call
|
||||
);
|
||||
|
||||
if ( !bStatus ) {
|
||||
printf("Ioctl failed with code %d\n", GetLastError() );
|
||||
break;
|
||||
} else {
|
||||
printf("Waiting for Event...\n");
|
||||
|
||||
WaitForSingleObject(setEvent.hEvent,
|
||||
INFINITE );
|
||||
|
||||
printf("Event signalled.\n\n");
|
||||
|
||||
ResetEvent( setEvent.hEvent);
|
||||
//printf("Event reset.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// close the driver
|
||||
//
|
||||
if ( !CloseHandle(hDevice) ) {
|
||||
printf("Failed to close device.\n");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
7
reactos/drivers/dd/event/exe/makefile
Normal file
7
reactos/drivers/dd/event/exe/makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the driver components of the Windows NT DDK
|
||||
#
|
||||
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
10
reactos/drivers/dd/event/exe/sources
Normal file
10
reactos/drivers/dd/event/exe/sources
Normal file
@@ -0,0 +1,10 @@
|
||||
TARGETNAME=event
|
||||
TARGETPATH=$(BASEDIR)\lib
|
||||
TARGETTYPE=PROGRAM
|
||||
|
||||
INCLUDES=..\sys
|
||||
|
||||
SOURCES=eventtest.c
|
||||
|
||||
UMTYPE=console
|
||||
UMBASE=0x100000
|
50
reactos/drivers/dd/event/readme.txt
Normal file
50
reactos/drivers/dd/event/readme.txt
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
This sample demonstrates one way that a Windows NT kernel-mode device driver
|
||||
can share and explicitly signal an Event Object with a Win32 application.
|
||||
It is composed of two parts, a Windows NT kernel-mode device driver and a Win32
|
||||
console test application. Both are built using the Windows NT DDK.
|
||||
|
||||
|
||||
Instructions:
|
||||
-------------
|
||||
|
||||
1) Build the driver and test application in either the FREE or CHECKED build environment:
|
||||
|
||||
BLD
|
||||
|
||||
Both the driver and application are put in %NTDDK%\LIB\*\FREE | CHECKED on your build machine.
|
||||
|
||||
|
||||
2) Copy the newly built driver to your Target machine's %SystemRoot%\system32\drivers
|
||||
directory. Copy the newly built application to your target machine.
|
||||
Also copy the EVENT.INI file to your Target machine.
|
||||
|
||||
|
||||
3) Update the Target machine's Registry by running REGINI.EXE on the EVENT.INI file, i.e.:
|
||||
|
||||
REGINI EVENT.INI
|
||||
|
||||
This adds a driver key under the
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services tree in the Registry.
|
||||
You can verify this by running REGEDIT32.EXE and looking at the \Event key.
|
||||
|
||||
|
||||
4) Reboot the Target machine for the Registry changes to take effect.
|
||||
Your driver will not load until you reboot.
|
||||
|
||||
|
||||
5) Load the driver from the command line:
|
||||
|
||||
NET START EVENT
|
||||
|
||||
|
||||
6) Run the test app from the command line:
|
||||
|
||||
EVENT <DELAY>
|
||||
|
||||
where DELAY = time to delay the Event signal in seconds.
|
||||
|
||||
|
||||
7) Unload the driver from the command line:
|
||||
|
||||
NET STOP EVENT
|
447
reactos/drivers/dd/event/sys/event.c
Normal file
447
reactos/drivers/dd/event/sys/event.c
Normal file
@@ -0,0 +1,447 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Event.c
|
||||
|
||||
Abstract:
|
||||
|
||||
This sample demonstrates one way that a Windows NT kernel-mode driver
|
||||
can share and explicitly signal an Event Object with a Win32 application.
|
||||
|
||||
This sample uses the following method:
|
||||
The application creates an event object using CreateEvent().
|
||||
The app passes the event handle to the driver in a private IOCTL.
|
||||
The driver is running in the app's thread context during the IOCTL so
|
||||
there is a valid user-mode handle at that time.
|
||||
The driver dereferences the user-mode handle into system space & saves
|
||||
the new system handle for later use.
|
||||
The driver signals the event via KeSetEvent() at IRQL <= DISPATCH_LEVEL.
|
||||
The driver MUST delete any driver references to the event object at
|
||||
Unload time.
|
||||
|
||||
An alternative method would be to create a named event in the driver via
|
||||
IoCreateNotificationEvent and then open the event in user mode. This API
|
||||
however is new to Windows NT 4.0 so you can not use this method in your
|
||||
NT 3.5x drivers.
|
||||
|
||||
Note that this sample's event can be signalled (almost) at will from within
|
||||
the driver. A different event signal can be set when the driver is setup to
|
||||
do asynchronous I/O, and it is opened with FILE_FLAG_OVERLAPPED, and an
|
||||
event handle is passed down in an OVERLAPPED struct from the app's Read,
|
||||
Write, or DeviceIoControl. This different event signal is set by the I/O
|
||||
Manager when the driver calls IoCompleteRequest on a pending Irp. This type
|
||||
of Irp completion signal is not the purpose of this sample, hence the lack of
|
||||
Irp queing.
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
Kernel Mode Only
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// INCLUDES
|
||||
//
|
||||
#include "ntddk.h"
|
||||
#include "event.h"
|
||||
|
||||
//
|
||||
// DEFINES
|
||||
//
|
||||
#define USER_NAME L"\\DosDevices\\EVENT"
|
||||
#define SYSTEM_NAME L"\\Device\\EVENT"
|
||||
|
||||
//
|
||||
// DATA
|
||||
//
|
||||
typedef struct _DEVICE_EXTENSION {
|
||||
KDPC Dpc;
|
||||
KTIMER Timer;
|
||||
HANDLE hEvent;
|
||||
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
||||
|
||||
//
|
||||
// PROTOS
|
||||
//
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Unload(
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
Dispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
);
|
||||
|
||||
VOID
|
||||
CustomTimerDPC(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2
|
||||
);
|
||||
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine gets called by the system to initialize the driver.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverObject - the system supplied driver object.
|
||||
RegistryPath - the system supplied registry path for this driver.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject;
|
||||
PDEVICE_EXTENSION pDeviceExtension;
|
||||
|
||||
UNICODE_STRING usSystemName;
|
||||
UNICODE_STRING usUserName;
|
||||
|
||||
NTSTATUS status;
|
||||
|
||||
|
||||
KdPrint(("Event!DriverEntry - IN\n"));
|
||||
|
||||
//
|
||||
// create the device object
|
||||
//
|
||||
RtlInitUnicodeString( &usSystemName, SYSTEM_NAME );
|
||||
|
||||
status = IoCreateDevice(
|
||||
DriverObject, // DriverObject
|
||||
sizeof( DEVICE_EXTENSION ), // DeviceExtensionSize
|
||||
&usSystemName, // DeviceName
|
||||
FILE_DEVICE_UNKNOWN, // DeviceType
|
||||
0, // DeviceCharacteristics
|
||||
TRUE, // Exclusive
|
||||
&pDeviceObject // DeviceObject
|
||||
);
|
||||
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
KdPrint(("\tIoCreateDevice returned 0x%x\n", status));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
//
|
||||
// Set up dispatch entry points for the driver.
|
||||
//
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] =
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Dispatch;
|
||||
DriverObject->DriverUnload = Unload;
|
||||
|
||||
//
|
||||
// Create a symbolic link into user mode for the driver.
|
||||
//
|
||||
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||
status = IoCreateSymbolicLink( &usUserName, &usSystemName );
|
||||
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
IoDeleteDevice( pDeviceObject );
|
||||
KdPrint(("\tIoCreateSymbolicLink returned 0x%x\n", status));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
//
|
||||
// establish user-buffer access method
|
||||
//
|
||||
pDeviceObject->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
|
||||
//
|
||||
// setup the device extension
|
||||
//
|
||||
pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
|
||||
KeInitializeDpc(
|
||||
&pDeviceExtension->Dpc, // Dpc
|
||||
CustomTimerDPC, // DeferredRoutine
|
||||
pDeviceObject // DeferredContext
|
||||
);
|
||||
|
||||
KeInitializeTimer(
|
||||
&pDeviceExtension->Timer // Timer
|
||||
);
|
||||
|
||||
pDeviceExtension->hEvent = NULL;
|
||||
|
||||
KdPrint(("Event!DriverEntry - OUT\n"));
|
||||
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Unload(
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine gets called to remove the driver from the system.
|
||||
|
||||
Arguments:
|
||||
|
||||
DriverObject - the system supplied driver object.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject = DriverObject->DeviceObject;
|
||||
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
UNICODE_STRING usUserName;
|
||||
|
||||
|
||||
KdPrint(("Event!Unload\n"));
|
||||
|
||||
//
|
||||
// dereference the event object or it will NEVER go away until reboot
|
||||
//
|
||||
if ( pDeviceExtension->hEvent )
|
||||
ObDereferenceObject( pDeviceExtension->hEvent );
|
||||
|
||||
// Delete the user-mode symbolic link.
|
||||
RtlInitUnicodeString( &usUserName, USER_NAME );
|
||||
IoDeleteSymbolicLink( &usUserName );
|
||||
|
||||
// Delete the DeviceObject
|
||||
IoDeleteDevice( pDeviceObject );
|
||||
|
||||
return( STATUS_SUCCESS );
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS
|
||||
Dispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This device control dispatcher handles IOCTLs.
|
||||
|
||||
Arguments:
|
||||
|
||||
DeviceObject - Context for the activity.
|
||||
Irp - The device control argument block.
|
||||
|
||||
Return Value:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_EXTENSION pDeviceExtension;
|
||||
PIO_STACK_LOCATION pIrpStack;
|
||||
PSET_EVENT pSetEvent;
|
||||
|
||||
ULONG ulInformation = 0L;
|
||||
NTSTATUS status = STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
|
||||
KdPrint(("Event!Dispatch - IN\n"));
|
||||
|
||||
pDeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
pIrpStack = IoGetCurrentIrpStackLocation( Irp );
|
||||
|
||||
switch( pIrpStack->MajorFunction )
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
case IRP_MJ_CLOSE:
|
||||
KdPrint(("\t%s\n", (IRP_MJ_CREATE == pIrpStack->MajorFunction) ? "IRP_MJ_CREATE" : "IRP_MJ_CLOSE"));
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_DEVICE_CONTROL:
|
||||
switch( pIrpStack->Parameters.DeviceIoControl.IoControlCode )
|
||||
{
|
||||
case IOCTL_SET_EVENT:
|
||||
KdPrint(("\tIOCTL_SET_EVENT\n"));
|
||||
|
||||
if ( pIrpStack->Parameters.DeviceIoControl.InputBufferLength < SIZEOF_SETEVENT ) {
|
||||
// Parameters are invalid
|
||||
KdPrint(("\tSTATUS_INVALID_PARAMETER\n"));
|
||||
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
} else {
|
||||
pSetEvent = (PSET_EVENT)Irp->AssociatedIrp.SystemBuffer;
|
||||
KdPrint(("\tuser-mode HANDLE = 0x%x\n", pSetEvent->hEvent ));
|
||||
|
||||
status = ObReferenceObjectByHandle( pSetEvent->hEvent,
|
||||
SYNCHRONIZE,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&pDeviceExtension->hEvent,
|
||||
NULL
|
||||
);
|
||||
if ( !NT_SUCCESS(status) ) {
|
||||
|
||||
KdPrint(("\tUnable to reference User-Mode Event object, Error = 0x%x\n", status));
|
||||
|
||||
} else {
|
||||
|
||||
KdPrint(("\tkernel-mode HANDLE = 0x%x\n", pDeviceExtension->hEvent ));
|
||||
|
||||
//
|
||||
// Start the timer to run the CustomTimerDPC in DueTime seconds to
|
||||
// simulate an interrupt (which would queue a DPC).
|
||||
// The user's event object is signaled in the DPC.
|
||||
//
|
||||
|
||||
// ensure relative time for this sample
|
||||
if ( pSetEvent->DueTime.QuadPart > 0 )
|
||||
pSetEvent->DueTime.QuadPart = -(pSetEvent->DueTime.QuadPart);
|
||||
KdPrint(("\tDueTime = %d\n", pSetEvent->DueTime.QuadPart ));
|
||||
|
||||
KeSetTimer(
|
||||
&pDeviceExtension->Timer, // Timer
|
||||
pSetEvent->DueTime, // DueTime
|
||||
&pDeviceExtension->Dpc // Dpc
|
||||
);
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// should never hit this
|
||||
ASSERT(0);
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
} // switch IoControlCode
|
||||
break;
|
||||
|
||||
default:
|
||||
// should never hit this
|
||||
ASSERT(0);
|
||||
status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
} // switch MajorFunction
|
||||
|
||||
|
||||
//
|
||||
// complete the Irp
|
||||
//
|
||||
Irp->IoStatus.Status = status;
|
||||
Irp->IoStatus.Information = ulInformation;
|
||||
IoCompleteRequest( Irp, IO_NO_INCREMENT );
|
||||
|
||||
KdPrint(("Event!Dispatch - OUT\n"));
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
CustomTimerDPC(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This is the DPC associated with this drivers Timer object setup in DriverEntry.
|
||||
|
||||
Arguments:
|
||||
|
||||
Dpc - our DPC object associated with our Timer
|
||||
DeferredContext - Context for the DPC that we setup in DriverEntry
|
||||
SystemArgument1 -
|
||||
SystemArgument2 -
|
||||
|
||||
Return Value:
|
||||
|
||||
Nothing.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
|
||||
PDEVICE_OBJECT pDeviceObject = DeferredContext;
|
||||
PDEVICE_EXTENSION pDeviceExtension = pDeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
KdPrint(("Event!CustomTimerDPC - IN\n"));
|
||||
|
||||
//
|
||||
// Signal the Event created user-mode
|
||||
//
|
||||
// Note:
|
||||
// Do not call KeSetEvent from your ISR;
|
||||
// you must call it at IRQL <= DISPATCH_LEVEL.
|
||||
// Your ISR should queue a DPC and the DPC can
|
||||
// then call KeSetEvent on the ISR's behalf.
|
||||
//
|
||||
KeSetEvent((PKEVENT)pDeviceExtension->hEvent,// Event
|
||||
0, // Increment
|
||||
FALSE // Wait
|
||||
);
|
||||
|
||||
// there is no Irp to complete here
|
||||
|
||||
KdPrint(("Event!CustomTimerDPC - OUT\n"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
43
reactos/drivers/dd/event/sys/event.h
Normal file
43
reactos/drivers/dd/event/sys/event.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 1996 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Event.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Midkiff (jeffmi) 23-Jul-96
|
||||
|
||||
Enviroment:
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __EVENT__
|
||||
#define __EVENT__
|
||||
|
||||
|
||||
#include "devioctl.h"
|
||||
|
||||
typedef struct _SET_EVENT
|
||||
{
|
||||
HANDLE hEvent;
|
||||
LARGE_INTEGER DueTime; // requested DueTime in 100-nanosecond units
|
||||
|
||||
} SET_EVENT, *PSET_EVENT;
|
||||
|
||||
#define SIZEOF_SETEVENT sizeof(SET_EVENT)
|
||||
|
||||
|
||||
#define IOCTL_SET_EVENT \
|
||||
CTL_CODE( FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
||||
|
||||
|
||||
#endif // __EVENT__
|
7
reactos/drivers/dd/event/sys/event.ini
Normal file
7
reactos/drivers/dd/event/sys/event.ini
Normal file
@@ -0,0 +1,7 @@
|
||||
; note - the service name matches the driver's file (.sys) name
|
||||
|
||||
\Registry\Machine\System\CurrentControlSet\Services\Event
|
||||
Type = REG_DWORD 0x00000001
|
||||
Start = REG_DWORD 0x00000003
|
||||
Group = Extended Base
|
||||
ErrorControl = REG_DWORD 0x00000001
|
11
reactos/drivers/dd/event/sys/event.rc
Normal file
11
reactos/drivers/dd/event/sys/event.rc
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <ntverp.h>
|
||||
|
||||
#define VER_FILETYPE VFT_DRV
|
||||
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
|
||||
#define VER_FILEDESCRIPTION_STR "Sample Event Driver"
|
||||
#define VER_INTERNALNAME_STR "event.sys"
|
||||
|
||||
#include "common.ver"
|
||||
|
7
reactos/drivers/dd/event/sys/makefile
Normal file
7
reactos/drivers/dd/event/sys/makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||
# file to this component. This file merely indirects to the real make file
|
||||
# that is shared by all the driver components of the Windows NT DDK
|
||||
#
|
||||
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
6
reactos/drivers/dd/event/sys/sources
Normal file
6
reactos/drivers/dd/event/sys/sources
Normal file
@@ -0,0 +1,6 @@
|
||||
TARGETNAME=event
|
||||
TARGETPATH=$(BASEDIR)\lib
|
||||
TARGETTYPE=DRIVER
|
||||
|
||||
SOURCES=event.c \
|
||||
event.rc
|
444
reactos/drivers/dd/floppy/floppy.c
Normal file
444
reactos/drivers/dd/floppy/floppy.c
Normal file
@@ -0,0 +1,444 @@
|
||||
//
|
||||
// FLOPPY.C - NEC-765/8272A floppy device driver
|
||||
// written by Rex Jolliff
|
||||
// with help from various other sources, including but not limited to:
|
||||
// Art Baker's NT Device Driver Book, Linux Source, and the internet.
|
||||
//
|
||||
// Modification History:
|
||||
// 08/19/98 RJJ Created.
|
||||
//
|
||||
// To do:
|
||||
// FIXME: get it working
|
||||
// FIXME: add support for DMA hardware
|
||||
// FIXME: should add support for floppy tape/zip devices
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#include "floppy.h"
|
||||
|
||||
#define VERSION "V0.0.1"
|
||||
|
||||
// --------------------------------------------------- File Statics
|
||||
|
||||
typedef struct _FLOPPY_CONTROLLER_PARAMETERS
|
||||
{
|
||||
int PortBase;
|
||||
int Vector;
|
||||
int IrqL;
|
||||
int SynchronizeIrqL;
|
||||
KINTERRUPT_MODE InterruptMode;
|
||||
KAFFINITY Affinity;
|
||||
} FLOPPY_CONTROLLER_PARAMETERS, *PFLOPPY_CONTROLLER_PARAMETERS;
|
||||
|
||||
#define FLOPPY_MAX_CONTROLLERS 2
|
||||
FLOPPY_CONTROLLER_PARAMETERS ControllerParameters[FLOPPY_MAX_CONTROLLERS] =
|
||||
{
|
||||
{0x03f0, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
{0x0370, 6, 6, 6, LevelSensitive, 0xffff},
|
||||
};
|
||||
|
||||
FLOPPY_DEVICE_PARAMETERS DeviceTypes[] =
|
||||
{
|
||||
/* Unknown */
|
||||
{0, 500, 16, 16, 8000, 1000, 3000, 0, 20, 5, 80, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4, 8, 2, 1, 5, 3,10}, 1500, 0, "unknown"},
|
||||
/* 5 1/4 360 KB PC*/
|
||||
{1, 300, 16, 16, 8000, 1000, 3000, 0, 20, 5, 40, 3000, 17, {3,1,2,0,2}, 0, 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 1500, 1, "360K PC"},
|
||||
/* 5 1/4 HD AT*/
|
||||
{2, 500, 16, 16, 6000, 400, 3000, 14, 20, 6, 83, 3000, 17, {3,1,2,0,2}, 0, 0, { 2, 5, 6,23,10,20,11, 0}, 1500, 2, "1.2M"},
|
||||
/* 3 1/2 DD*/
|
||||
{3, 250, 16, 16, 3000, 1000, 3000, 0, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 4,22,21,30, 3, 0, 0, 0}, 1500, 4, "720k"},
|
||||
/* 3 1/2 HD*/
|
||||
{4, 500, 16, 16, 4000, 400, 3000, 10, 20, 5, 83, 3000, 20, {3,1,2,0,2}, 0, 0, { 7, 4,25,22,31,21,29,11}, 1500, 7, "1.44M"},
|
||||
/* 3 1/2 ED*/
|
||||
{5, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M AMI BIOS"},
|
||||
/* 3 1/2 ED*/
|
||||
{6, 1000, 15, 8, 3000, 400, 3000, 10, 20, 5, 83, 3000, 40, {3,1,2,0,2}, 0, 0, { 7, 8, 4,25,28,22,31,21}, 1500, 8, "2.88M"}
|
||||
};
|
||||
|
||||
static BOOLEAN FloppyInitialized = FALSE;
|
||||
|
||||
// ------------------------------------------------------ Functions
|
||||
|
||||
// ModuleEntry
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// This function initializes the driver, locates and claims
|
||||
// hardware resources, and creates various NT objects needed
|
||||
// to process I/O requests.
|
||||
//
|
||||
// RUN LEVEL:
|
||||
// PASSIVE_LEVEL
|
||||
//
|
||||
// ARGUMENTS:
|
||||
// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
|
||||
// for this driver
|
||||
// IN PUNICODE_STRING RegistryPath Name of registry driver service
|
||||
// key
|
||||
//
|
||||
// RETURNS:
|
||||
// NTSTATUS
|
||||
|
||||
NTSTATUS
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
NTSTATUS RC;
|
||||
PFLOPPY_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
// Export other driver entry points...
|
||||
DriverObject->DriverStartIo = FloppyStartIo;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = FloppyDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FloppyDispatchOpenClose;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = FloppyDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_WRITE] = FloppyDispatchReadWrite;
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FloppyDispatchDeviceControl;
|
||||
|
||||
// Try to detect controller and abort if it fails
|
||||
if (!FloppyCreateController(DriverObject,
|
||||
&ControllerParameters[0],
|
||||
0))
|
||||
{
|
||||
DPRINT("Could not find floppy controller");
|
||||
return STATUS_NO_SUCH_DEVICE;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FloppyCreateController(PDRIVER_OBJECT DriverObject,
|
||||
PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
int Index)
|
||||
{
|
||||
PFLOPPY_CONTROLLER_TYPE ControllerType;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
PFLOPPY_CONTROLLER_EXTENSION ControllerExtension;
|
||||
|
||||
/* Detect controller and determine type */
|
||||
if (!FloppyGetControllerVersion(ControllerParameters, &ControllerType))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: Register port ranges and interrupts with HAL
|
||||
|
||||
/* Create controller object for FDC */
|
||||
ControllerObject = IoCreateController(sizeof(FLOPPY_CONTROLLER_EXTENSION));
|
||||
if (ControllerObject == NULL)
|
||||
{
|
||||
DPRINT("Could not create controller object for controller %d\n",
|
||||
Index);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: fill out controller data
|
||||
ControllerExtension = (PFLOPPY_CONTROLLER_EXTENSION)
|
||||
ControllerObject->ControllerExtension;
|
||||
ControllerExtension->Number = Index;
|
||||
ControllerExtension->PortBase = ControllerParameters->PortBase;
|
||||
ControllerExtension->Vector = ControllerParameters->Vector;
|
||||
ControllerExtension->FDCType = ControllerType;
|
||||
|
||||
/* Initialize the spin lock in the controller extension */
|
||||
KeInitializeSpinLock(&ControllerExtension->SpinLock);
|
||||
|
||||
/* Register an interrupt handler for this controller */
|
||||
RC = IoConnectInterrupt(&ControllerExtension->Interrupt,
|
||||
FloppyIsr,
|
||||
ControllerExtension,
|
||||
&ControllerExtension->SpinLock,
|
||||
ControllerExtension->Vector,
|
||||
ControllerParameters->IrqL,
|
||||
ControllerParameters->SynchronizeIrqL,
|
||||
ControllerParameters->InterruptMode,
|
||||
FALSE,
|
||||
ControllerParameters->Affinity,
|
||||
FALSE);
|
||||
if (!NT_SUCCESS(RC))
|
||||
{
|
||||
DPRINT("Could not Connect Interrupt %d\n", ControllerExtension->Vector);
|
||||
IoDeleteController(ControllerObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FIXME: setup DMA stuff for controller
|
||||
|
||||
// Check for each possible drive and create devices for them
|
||||
for (DriveIdx = 0; DriveIdx < FLOPPY_MAX_DRIVES; DriveIdx++)
|
||||
{
|
||||
// FIXME: try to identify the drive
|
||||
// FIXME: create a device if it's there
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// FloppyGetControllerVersion
|
||||
//
|
||||
// DESCRIPTION
|
||||
// Get the type/version of the floppy controller
|
||||
//
|
||||
// RUN LEVEL:
|
||||
// PASSIVE_LEVEL
|
||||
//
|
||||
// ARGUMENTS:
|
||||
// IN OUT PFLOPPY_DEVICE_EXTENSION DeviceExtension
|
||||
//
|
||||
// RETURNS:
|
||||
// BOOL success or failure
|
||||
//
|
||||
// COMMENTS:
|
||||
// This routine (get_fdc_version) was originally written by David C. Niemi
|
||||
//
|
||||
static BOOLEAN
|
||||
FloppyGetControllerVersion(IN PFLOPPY_CONTROLLER_PARAMETERS ControllerParameters,
|
||||
OUT PFLOPPY_CONTROLLER_TYPE ControllerType)
|
||||
{
|
||||
BYTE ResultReturned
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
int ResultLength;
|
||||
|
||||
/* 82072 and better know DUMPREGS */
|
||||
if (!FloppyWriteCommandByte(ControllerParameters->PortBase,
|
||||
FLOPPY_CMD_DUMP_FDC))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 8272a/765 don't know DUMPREGS */
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is an 8272A\n", PortBase);
|
||||
*ControllerType = FDC_8272A;
|
||||
return TRUE;
|
||||
}
|
||||
if (r != 10)
|
||||
{
|
||||
DPRINT("FDC %d init: DUMP_FDC: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!FloppyConfigure(PortBase, FALSE, 0x0a))
|
||||
{
|
||||
DPRINT("FDC %d is an 82072\n", PortBase);
|
||||
*ControllerType = FDC_82072;
|
||||
return TRUE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PPND_RW);
|
||||
if (FloppyNeedsMoreOutput(PortBase, Result) == FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("FDC %d is an 82072A\n", PortBase);
|
||||
*ControllerType = FDC_82072A;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Pre-1991 82077, doesn't know LOCK/UNLOCK */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_UNLK_FIFO);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if ((ResultLength == 1) && (Result[0] == 0x80))
|
||||
{
|
||||
DPRINT("FDC %d is a pre-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077_ORIG;
|
||||
return TRUE;
|
||||
}
|
||||
if ((ResultLength != 1) || (Result[0] != 0x00))
|
||||
{
|
||||
DPRINT("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Revised 82077AA passes all the tests */
|
||||
FloppyWriteCommandByte(PortBase, FLOPPY_CMD_PARTID);
|
||||
ResultLength = FloppyReadResultCode(PortBase, &Result));
|
||||
if (ResultLength != 1)
|
||||
{
|
||||
DPRINT("FDC %d init: PARTID: unexpected return of %d bytes.\n",
|
||||
PortBase,
|
||||
ResultLength);
|
||||
return FALSE;
|
||||
}
|
||||
if (Result[0] == 0x80)
|
||||
{
|
||||
DPRINT("FDC %d is a post-1991 82077\n", PortBase);
|
||||
*ControllerType = FDC_82077;
|
||||
return TRUE;
|
||||
}
|
||||
switch (Result[0] >> 5)
|
||||
{
|
||||
case 0x0:
|
||||
/* Either a 82078-1 or a 82078SL running at 5Volt */
|
||||
DPRINT("FDC %d is an 82078.\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
case 0x1:
|
||||
DPRINT("FDC %d is a 44pin 82078\n", PortBase);
|
||||
*ControllerType = FDC_82078;
|
||||
return TRUE;
|
||||
|
||||
case 0x2:
|
||||
DPRINT("FDC %d is a S82078B\n", PortBase);
|
||||
*ControllerType = FDC_S82078B;
|
||||
return TRUE;
|
||||
|
||||
case 0x3:
|
||||
DPRINT("FDC %d is a National Semiconductor PC87306\n", PortBase);
|
||||
*ControllerType = FDC_87306;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
DPRINT("FDC %d init: 82078 variant with unknown PARTID=%d.\n",
|
||||
PortBase,
|
||||
Result[0] >> 5);
|
||||
*ControllerType = FDC_82078_UNKN;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* sends a command byte to the fdc */
|
||||
static BOOLEAN
|
||||
FloppyWriteCommandByte(WORD PortBase, BYTE Byte)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if ((Status = FloppyWaitUntilReady()) < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((Status & (STATUS_READY|STATUS_DIR|STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
FloppyWriteData(PortBase, Byte);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Unable to send byte %x to FDC. Fdc=%x Status=%x\n",
|
||||
Byte,
|
||||
PortBase,
|
||||
Status);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* gets the response from the fdc */
|
||||
static int
|
||||
FloppyReadResultCode(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Replies;
|
||||
int Status;
|
||||
|
||||
for (Replies = 0; Replies < FLOPPY_MAX_REPLIES; Replies++)
|
||||
{
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Status &= STATUS_DIR | STATUS_READY | STATUS_BUSY | STATUS_DMA;
|
||||
if ((Status & ~STATUS_BUSY) == STATUS_READY)
|
||||
{
|
||||
return Replies;
|
||||
}
|
||||
if (Status == (STATUS_DIR | STATUS_READY | STATUS_BUSY))
|
||||
{
|
||||
Result[Replies] = fd_inb(FD_DATA);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("get result error. Fdc=%d Last status=%x Read bytes=%d\n",
|
||||
PortBase,
|
||||
Status,
|
||||
Replies);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* waits until the fdc becomes ready */
|
||||
static int
|
||||
FloppyWaitUntilReady(WORD PortBase)
|
||||
{
|
||||
int Retries;
|
||||
int Status;
|
||||
|
||||
for (Retries = 0; Retries < FLOPPY_MAX_STAT_RETRIES; Retries++)
|
||||
{
|
||||
status = FloppyReadSTAT(PortBase);
|
||||
if (Status & STATUS_READY)
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (FloppyInitialized)
|
||||
{
|
||||
DPRINT("Getstatus times out (%x) on fdc %d\n",
|
||||
Status,
|
||||
PortBase);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define MORE_OUTPUT -2
|
||||
/* does the fdc need more output? */
|
||||
static int
|
||||
FloppyNeedsMoreOutput(WORD PortBase, PBYTE Result)
|
||||
{
|
||||
int Status;
|
||||
|
||||
if ((Status = FloppyWaitUntilReady(PortBase)) < 0)
|
||||
return -1;
|
||||
if ((Status & (STATUS_READY | STATUS_DIR | STATUS_DMA)) == STATUS_READY)
|
||||
{
|
||||
return FLOPPY_NEEDS_OUTPUT;
|
||||
}
|
||||
|
||||
return FloppyReadResultCode(PortBase, Result);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
FloppyConfigure(WORD PortBase, BOOLEAN DisableFIFO, BYTE FIFODepth)
|
||||
{
|
||||
BYTE Result[FLOPPY_MAX_REPLIES];
|
||||
|
||||
/* Turn on FIFO */
|
||||
FloppyWriteCommandByte(FLOPPY_CMD_CFG_FIFO);
|
||||
if (FloppyNeedsOutput(PortBase, Result) != FLOPPY_NEEDS_OUTPUT)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
FloppyWriteCommandByte(PortBase,
|
||||
0x10 |
|
||||
(DisableFIFO ? 0x20 : 0x00) |
|
||||
(FIFODepth & 0x0f));
|
||||
/* pre-compensation from track 0 upwards */
|
||||
FloppyWriteCommandByte(PortBase, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
158
reactos/drivers/dd/floppy/floppy.h
Normal file
158
reactos/drivers/dd/floppy/floppy.h
Normal file
@@ -0,0 +1,158 @@
|
||||
|
||||
#define FLOPPY_MAX_STAT_RETRIES 10000
|
||||
|
||||
#define FLOPPY_NEEDS_OUTPUT -2
|
||||
//
|
||||
// Floppy register definitions
|
||||
//
|
||||
|
||||
#define FLOPPY_REG_DOR 0x0002
|
||||
#define FLOPPY_REG_MSTAT 0x0004
|
||||
#define FLOPPY_MS_DRV0BUSY 0x01
|
||||
#define FLOPPY_MS_DRV1BUSY 0x02
|
||||
#define FLOPPY_MS_DRV2BUSY 0x04
|
||||
#define FLOPPY_MS_DRV3BUSY 0x08
|
||||
#define FLOPPY_MS_FDCBUSY 0x10
|
||||
#define FLOPPY_MS_DMAMODE 0x20
|
||||
#define FLOPPY_MS_DATADIR 0x40
|
||||
#define FLOPPY_MS_DATARDY 0x80
|
||||
#define FLOPPY_REG_DATA 0x0005
|
||||
#define FLOPPY_REG_DIR 0x0007 /* READ ONLY */
|
||||
#define FLOPPY_DI_DSKCHNG 0x80
|
||||
#define FLOPPY_REG_CCNTL 0x0007 /* WRITE ONLY */
|
||||
|
||||
#define FLOPPY_CMD_RD_TRK 0x02
|
||||
#define FLOPPY_CMD_SPEC_CHARS 0x03
|
||||
#define FLOPPY_CSC_SRT_SHIFT 4
|
||||
#define FLOPPY_CSC_HUT_MASK 0x0f
|
||||
#define FLOPPY_CSC_HLT_SHIFT 1
|
||||
#define FLOPPY_CSC_NON_DMA 0x01
|
||||
#define FLOPPY_CMD_SNS_DRV 0x04
|
||||
#define FLOPPY_CMD_WRT_DATA 0x05
|
||||
#define FLOPPY_CMD_RD_DATA 0x06
|
||||
#define FLOPPY_CMD_RECAL 0x07
|
||||
#define FLOPPY_CMD_SNS_INTR 0x08
|
||||
#define FLOPPY_CSI_IC_MASK 0xe0
|
||||
#define FLOPPY_CSI_IC_RDYCH 0x60
|
||||
#define FLOPPY_CSI_IC_SEEKGD 0x80
|
||||
#define FLOPPY_CSI_IC_SEEKBD 0xc0
|
||||
#define FLOPPY_CMD_WRT_DEL 0x09
|
||||
#define FLOPPY_CMD_RD_ID 0x0a
|
||||
#define FLOPPY_CMD_RD_DEL 0x0c
|
||||
#define FLOPPY_CMD_FMT_TRK 0x0d
|
||||
#define FLOPPY_CMD_DUMP_FDC 0x0e
|
||||
#define FLOPPY_CMD_SEEK 0x0f
|
||||
#define FLOPPY_CMD_VERSION 0x10
|
||||
#define FLOPPY_CMD_SCN_EQ 0x11
|
||||
#define FLOPPY_CMD_PPND_RW 0x12
|
||||
#define FLOPPY_CMD_CFG_FIFO 0x13
|
||||
#define FLOPPY_CMD_LCK_FIFO 0x14
|
||||
#define FLOPPY_CMD_PARTID 0x18
|
||||
#define FLOPPY_CMD_SCN_LE 0x19
|
||||
#define FLOPPY_CMD_SCN_GE 0x1d
|
||||
#define FLOPPY_CMD_CFG_PWR 0x27
|
||||
#define FLOPPY_CMD_SAVE_FDC 0x2e
|
||||
#define FLOPPY_CMD_FMT_ISO 0x33
|
||||
#define FLOPPY_CMD_DMA_READ 0x46
|
||||
#define FLOPPY_CMD_DMA_WRT 0x4a
|
||||
#define FLOPPY_CMD_REST_FDC 0x4e
|
||||
#define FLOPPY_CMD_DRV_SPEC 0x8e
|
||||
#define FLOPPY_CMD_RSEEK_OUT 0x8f
|
||||
#define FLOPPY_CMD_ULK_FIFO 0x94
|
||||
#define FLOPPY_CMD_RSEEK_IN 0xcf
|
||||
#define FLOPPY_CMD_FMT_WRT 0xef
|
||||
|
||||
// Command Code modifiers
|
||||
#define FLOPPY_C0M_SK 0x20
|
||||
#define FLOPPY_C0M_MFM 0x40
|
||||
#define FLOPPY_C0M_MT 0x80
|
||||
#define FLOPPY_C1M_DRVMASK 0x03
|
||||
#define FLOPPY_C1M_HEAD1 0x04
|
||||
|
||||
// Status code values and masks
|
||||
#define FLOPPY_ST0_INVALID 0x80
|
||||
|
||||
// useful command defines
|
||||
#define FLOPPY_CMD_READ (FLOPPY_CMD_RD_DATA | FLOPPY_C0M_SK | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
|
||||
#define FLOPPY_CMD_WRITE (FLOPPY_CMD_WRT_DATA | FLOPPY_C0M_MFM | FLOPPY_C0M_MT)
|
||||
#define FLOPPY_CMD_FORMAT (FLOPPY_CMD_FMT_TRK | FLOPPY_C0M_MFM)
|
||||
|
||||
//
|
||||
// HAL floppy register access commands
|
||||
//
|
||||
#define FloppyWriteDOR(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DOR, (V)))
|
||||
#define FloppyReadMSTAT(A) (READ_BYTE((A) + FLOPPY_REG_MSTAT))
|
||||
#define FloppyReadDATA(A) (READ_BYTE((A) + FLOPPY_REG_DATA))
|
||||
#define FloppyWriteDATA(A, V) (WRITE_BYTE((A) + FLOPPY_REG_DATA, (V)))
|
||||
#define FloppyReadDIR(A) (READ_BYTE((A) + FLOPPY_REG_DIR))
|
||||
#define FloppyWriteCCNTL(A, V) (WRITE_BYTE((A) + FLOPPY_REG_CCNTL, (V)))
|
||||
|
||||
//
|
||||
// Known Floppy controller types
|
||||
//
|
||||
typedef enum _FLOPPY_CONTROLLER_TYPE
|
||||
{
|
||||
FDC_NONE,
|
||||
FDC_UNKNOWN,
|
||||
FDC_8272A, /* Intel 8272a, NEC 765 */
|
||||
FDC_765ED, /* Non-Intel 1MB-compatible FDC, can't detect */
|
||||
FDC_82072, /* Intel 82072; 8272a + FIFO + DUMPREGS */
|
||||
FDC_82072A, /* 82072A (on Sparcs) */
|
||||
FDC_82077_ORIG, /* Original version of 82077AA, sans LOCK */
|
||||
FDC_82077, /* 82077AA-1 */
|
||||
FDC_82078_UNKN, /* Unknown 82078 variant */
|
||||
FDC_82078, /* 44pin 82078 or 64pin 82078SL */
|
||||
FDC_82078_1, /* 82078-1 (2Mbps fdc) */
|
||||
FDC_S82078B, /* S82078B (first seen on Adaptec AVA-2825 VLB SCSI/EIDE/Floppy controller) */
|
||||
FDC_87306 /* National Semiconductor PC 87306 */
|
||||
} FLOPPY_CONTROLLER_TYPE, *PFLOPPY_CONTROLLER_TYPE;
|
||||
|
||||
typedef struct _FLOPPY_ERROR_THRESHOLDS
|
||||
{
|
||||
/* number of errors to be reached before aborting */
|
||||
unsigned int Abort;
|
||||
/* maximal number of errors permitted to read an entire track at once */
|
||||
unsigned int ReadTrack;
|
||||
/* maximal number of errors before a reset is tried */
|
||||
unsigned int Reset;
|
||||
/* maximal number of errors before a recalibrate is tried */
|
||||
unsigned int Recal;
|
||||
/*
|
||||
* Threshold for reporting FDC errors to the console.
|
||||
* Setting this to zero may flood your screen when using
|
||||
* ultra cheap floppies ;-)
|
||||
*/
|
||||
unsigned int Reporting;
|
||||
} FLOPPY_ERROR_THRESHOLDS;
|
||||
|
||||
#define FDP_DEBUG 0x02
|
||||
#define FDP_SILENT_DCL_CLEAR 0x04
|
||||
#define FDP_MSG 0x10
|
||||
#define FDP_BROKEN_DCL 0x20
|
||||
#define FDP_INVERTED_DCL 0x80
|
||||
|
||||
typedef struct _FLOPPY_DEVICE_PARAMETERS
|
||||
{
|
||||
char CMOSType;
|
||||
unsigned long MaxDTR; /* Step rate, usec */
|
||||
unsigned long HLT; /* Head load/settle time, msec */
|
||||
unsigned long HUT; /* Head unload time (remnant of 8" drives) */
|
||||
unsigned long SRT; /* Step rate, usec */
|
||||
unsigned long Spinup; /* time needed for spinup */
|
||||
unsigned long Spindown; /* timeout needed for spindown */
|
||||
unsigned char SpindownOffset; /* decides in which position the disk will stop */
|
||||
unsigned char SelectDelay; /* delay to wait after select */
|
||||
unsigned char RPS; /* rotations per second */
|
||||
unsigned char Tracks; /* maximum number of tracks */
|
||||
unsigned long Timeout; /* timeout for interrupt requests */
|
||||
unsigned char InterleaveSect; /* if there are more sectors, use interleave */
|
||||
FLOPPY_ERROR_THRESHOLDS MaxErrors;
|
||||
char Flags; /* various flags, including ftd_msg */
|
||||
BOOLEAN ReadTrack; /* use readtrack during probing? */
|
||||
short Autodetect[8]; /* autodetected formats */
|
||||
int CheckFreq; /* how often should the drive be checked for disk changes */
|
||||
int NativeFormat; /* native format of this drive */
|
||||
char *DriveName; /* name of the drive for reporting */
|
||||
} FLOPPY_DEVICE_PARAMETERS, *PFLOPPY_DEVICE_PARAMETERS;
|
||||
|
||||
|
3
reactos/drivers/dd/ide/.cvsignore
Normal file
3
reactos/drivers/dd/ide/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
2058
reactos/drivers/dd/ide/ide.c
Normal file
2058
reactos/drivers/dd/ide/ide.c
Normal file
File diff suppressed because it is too large
Load Diff
235
reactos/drivers/dd/ide/ide.h
Normal file
235
reactos/drivers/dd/ide/ide.h
Normal file
@@ -0,0 +1,235 @@
|
||||
//
|
||||
// IDE.H - defines and typedefs for the IDE Driver module.
|
||||
//
|
||||
|
||||
#ifndef __IDE_H
|
||||
#define __IDE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IDE_MAXIMUM_DEVICES 8
|
||||
|
||||
#define IDE_MAX_NAME_LENGTH 50
|
||||
#define IDE_NT_ROOTDIR_NAME "\\Device"
|
||||
#define IDE_NT_DEVICE_NAME "\\Harddisk"
|
||||
#define IDE_NT_PARTITION_NAME "\\Partition"
|
||||
#define IDE_WIN32_DEVICE_NAME "\\DosDevices\\IDE"
|
||||
#define IDE_DRIVER_NAME "IDEDRIVER"
|
||||
|
||||
#define IDE_SECTOR_BUF_SZ 512
|
||||
#define IDE_MAX_SECTORS_PER_XFER 256
|
||||
#define IDE_MAX_RESET_RETRIES 10000
|
||||
#define IDE_MAX_POLL_RETRIES 100000
|
||||
#define IDE_MAX_WRITE_RETRIES 1000
|
||||
#define IDE_MAX_BUSY_RETRIES 100
|
||||
//#define IDE_MAX_BUSY_RETRIES 100000
|
||||
#define IDE_MAX_DRQ_RETRIES 10000
|
||||
//#define IDE_MAX_CMD_RETRIES 1
|
||||
#define IDE_MAX_CMD_RETRIES 0
|
||||
#define IDE_CMD_TIMEOUT 5
|
||||
#define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */
|
||||
#define IDE_RESET_BUSY_TIMEOUT 31
|
||||
#define IDE_RESET_DRDY_TIMEOUT 120
|
||||
|
||||
// Control Block offsets and masks
|
||||
#define IDE_REG_ALT_STATUS 0x0000
|
||||
#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
|
||||
#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
|
||||
#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
|
||||
#define IDE_REG_DRV_ADDR 0x0001
|
||||
|
||||
// Command Block offsets and masks
|
||||
#define IDE_REG_DATA_PORT 0x0000
|
||||
#define IDE_REG_ERROR 0x0001 /* error register */
|
||||
#define IDE_ER_AMNF 0x01 /* addr mark not found */
|
||||
#define IDE_ER_TK0NF 0x02 /* track 0 not found */
|
||||
#define IDE_ER_ABRT 0x04 /* command aborted */
|
||||
#define IDE_ER_MCR 0x08 /* media change requested */
|
||||
#define IDE_ER_IDNF 0x10 /* ID not found */
|
||||
#define IDE_ER_MC 0x20 /* Media changed */
|
||||
#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
|
||||
#define IDE_REG_PRECOMP 0x0001
|
||||
#define IDE_REG_SECTOR_CNT 0x0002
|
||||
#define IDE_REG_SECTOR_NUM 0x0003
|
||||
#define IDE_REG_CYL_LOW 0x0004
|
||||
#define IDE_REG_CYL_HIGH 0x0005
|
||||
#define IDE_REG_DRV_HEAD 0x0006
|
||||
#define IDE_DH_FIXED 0xA0
|
||||
#define IDE_DH_LBA 0x40
|
||||
#define IDE_DH_HDMASK 0x0F
|
||||
#define IDE_DH_DRV0 0x00
|
||||
#define IDE_DH_DRV1 0x10
|
||||
#define IDE_REG_STATUS 0x0007
|
||||
#define IDE_SR_BUSY 0x80
|
||||
#define IDE_SR_DRDY 0x40
|
||||
#define IDE_SR_DRQ 0x08
|
||||
#define IDE_SR_ERR 0x01
|
||||
#define IDE_REG_COMMAND 0x0007
|
||||
#define IDE_CMD_READ 0x20
|
||||
#define IDE_CMD_READ_RETRY 0x21
|
||||
#define IDE_CMD_WRITE 0x30
|
||||
#define IDE_CMD_WRITE_RETRY 0x31
|
||||
#define IDE_CMD_IDENT_DRV 0xEC
|
||||
|
||||
//
|
||||
// Access macros for command registers
|
||||
// Each macro takes an address of the command port block, and data
|
||||
//
|
||||
#define IDEReadError(Address) (inb_p((Address) + IDE_REG_ERROR))
|
||||
#define IDEWritePrecomp(Address, Data) (outb_p((Address) + IDE_REG_PRECOMP, (Data)))
|
||||
#define IDEReadSectorCount(Address) (inb_p((Address) + IDE_REG_SECTOR_CNT))
|
||||
#define IDEWriteSectorCount(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_CNT, (Data)))
|
||||
#define IDEReadSectorNum(Address) (inb_p((Address) + IDE_REG_SECTOR_NUM))
|
||||
#define IDEWriteSectorNum(Address, Data) (outb_p((Address) + IDE_REG_SECTOR_NUM, (Data)))
|
||||
#define IDEReadCylinderLow(Address) (inb_p((Address) + IDE_REG_CYL_LOW))
|
||||
#define IDEWriteCylinderLow(Address, Data) (outb_p((Address) + IDE_REG_CYL_LOW, (Data)))
|
||||
#define IDEReadCylinderHigh(Address) (inb_p((Address) + IDE_REG_CYL_HIGH))
|
||||
#define IDEWriteCylinderHigh(Address, Data) (outb_p((Address) + IDE_REG_CYL_HIGH, (Data)))
|
||||
#define IDEReadDriveHead(Address) (inb_p((Address) + IDE_REG_DRV_HEAD))
|
||||
#define IDEWriteDriveHead(Address, Data) (outb_p((Address) + IDE_REG_DRV_HEAD, (Data)))
|
||||
#define IDEReadStatus(Address) (inb_p((Address) + IDE_REG_STATUS))
|
||||
#define IDEWriteCommand(Address, Data) (outb_p((Address) + IDE_REG_COMMAND, (Data)))
|
||||
|
||||
//
|
||||
// Data block read and write commands
|
||||
//
|
||||
#define IDEReadBlock(Address, Buffer, Count) \
|
||||
(insw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
#define IDEWriteBlock(Address, Buffer, Count) \
|
||||
(outsw((Address) + IDE_REG_DATA_PORT, (Buffer), (Count) / 2))
|
||||
|
||||
//
|
||||
// Access macros for control registers
|
||||
// Each macro takes an address of the control port blank and data
|
||||
//
|
||||
#define IDEWriteDriveControl(Address, Data) (outb_p((Address) + IDE_REG_DEV_CNTRL, (Data)))
|
||||
|
||||
// IDE_DEVICE_EXTENSION
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Extension to be placed in each device object
|
||||
//
|
||||
// ACCESS:
|
||||
// Allocated from NON-PAGED POOL
|
||||
// Available at any IRQL
|
||||
//
|
||||
|
||||
typedef struct _IDE_DEVICE_EXTENSION {
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PCONTROLLER_OBJECT ControllerObject;
|
||||
struct _IDE_DEVICE_EXTESION *DiskExtension;
|
||||
int UnitNumber;
|
||||
BOOLEAN LBASupported;
|
||||
BOOLEAN DMASupported;
|
||||
int BytesPerSector;
|
||||
int LogicalHeads;
|
||||
int SectorsPerLogCyl;
|
||||
int SectorsPerLogTrk;
|
||||
int Offset;
|
||||
int Size;
|
||||
|
||||
int Operation;
|
||||
ULONG BytesRequested;
|
||||
ULONG BytesToTransfer;
|
||||
ULONG BytesRemaining;
|
||||
ULONG StartingSector;
|
||||
int SectorsTransferred;
|
||||
BYTE *TargetAddress;
|
||||
|
||||
} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION;
|
||||
|
||||
// IDE_TIMER_STATES
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// An enumeration containing the states in the timer DFA
|
||||
//
|
||||
|
||||
typedef enum _IDE_TIMER_STATES {
|
||||
IDETimerIdle,
|
||||
IDETimerCmdWait,
|
||||
IDETimerResetWaitForBusyNegate,
|
||||
IDETimerResetWaitForDrdyAssert
|
||||
} IDE_TIMER_STATES;
|
||||
|
||||
// IDE_CONTROLLER_EXTENSION
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Driver-defined structure used to hold miscellaneous controller information.
|
||||
//
|
||||
// ACCESS:
|
||||
// Allocated from NON-PAGED POOL
|
||||
// Available at any IRQL
|
||||
//
|
||||
|
||||
typedef struct _IDE_CONTROLLER_EXTENSION {
|
||||
KSPIN_LOCK SpinLock;
|
||||
int Number;
|
||||
int Vector;
|
||||
int CommandPortBase;
|
||||
int ControlPortBase;
|
||||
BOOLEAN DMASupported;
|
||||
BOOLEAN ControllerInterruptBug;
|
||||
PKINTERRUPT Interrupt;
|
||||
|
||||
BOOLEAN OperationInProgress;
|
||||
BYTE DeviceStatus;
|
||||
PIDE_DEVICE_EXTENSION DeviceForOperation;
|
||||
PIRP CurrentIrp;
|
||||
int Retries;
|
||||
|
||||
IDE_TIMER_STATES TimerState;
|
||||
LONG TimerCount;
|
||||
PDEVICE_OBJECT TimerDevice;
|
||||
|
||||
} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION;
|
||||
|
||||
// IDE_DRIVE_IDENTIFY
|
||||
|
||||
typedef struct _IDE_DRIVE_IDENTIFY {
|
||||
WORD ConfigBits; /*00*/
|
||||
WORD LogicalCyls; /*01*/
|
||||
WORD Reserved02; /*02*/
|
||||
WORD LogicalHeads; /*03*/
|
||||
WORD BytesPerTrack; /*04*/
|
||||
WORD BytesPerSector; /*05*/
|
||||
WORD SectorsPerTrack; /*06*/
|
||||
BYTE InterSectorGap; /*07*/
|
||||
BYTE InterSectorGapSize;
|
||||
BYTE Reserved08H; /*08*/
|
||||
BYTE BytesInPLO;
|
||||
WORD VendorUniqueCnt; /*09*/
|
||||
char SerialNumber[20]; /*10*/
|
||||
WORD ControllerType; /*20*/
|
||||
WORD BufferSize; /*21*/
|
||||
WORD ECCByteCnt; /*22*/
|
||||
char FirmwareRev[8]; /*23*/
|
||||
char ModelNumber[40]; /*27*/
|
||||
WORD RWMultImplemented; /*47*/
|
||||
WORD Reserved48; /*48*/
|
||||
WORD Capabilities; /*49*/
|
||||
#define IDE_DRID_STBY_SUPPORTED 0x2000
|
||||
#define IDE_DRID_IORDY_SUPPORTED 0x0800
|
||||
#define IDE_DRID_IORDY_DISABLE 0x0400
|
||||
#define IDE_DRID_LBA_SUPPORTED 0x0200
|
||||
#define IDE_DRID_DMA_SUPPORTED 0x0100
|
||||
WORD Reserved50; /*50*/
|
||||
WORD MinPIOTransTime; /*51*/
|
||||
WORD MinDMATransTime; /*52*/
|
||||
WORD TMFieldsValid; /*53*/
|
||||
WORD TMCylinders; /*54*/
|
||||
WORD TMHeads; /*55*/
|
||||
WORD TMSectorsPerTrk; /*56*/
|
||||
WORD TMCapacity; /*57*/
|
||||
WORD Reserved53[198]; /*58*/
|
||||
} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IDE_H */
|
||||
|
||||
|
39
reactos/drivers/dd/ide/ide.rc
Normal file
39
reactos/drivers/dd/ide/ide.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "IDE Disk Device Driver\0"
|
||||
VALUE "FileVersion", "0.1.4\0"
|
||||
VALUE "InternalName", "ide\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "ide.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
20
reactos/drivers/dd/ide/idep.h
Normal file
20
reactos/drivers/dd/ide/idep.h
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
#define IOCTL_DISK_GET_DRIVE_GEOMETRY CTL_CODE(FILE_DEVICE_DISK, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_GET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 1, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DISK_SET_PARTITION_INFO CTL_CODE(FILE_DEVICE_DISK, 2, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_GET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 3, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DISK_SET_DRIVE_LAYOUT CTL_CODE(FILE_DEVICE_DISK, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_VERIFY CTL_CODE(FILE_DEVICE_DISK, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_FORMAT_TRACKS CTL_CODE(FILE_DEVICE_DISK, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_REASSIGN_BLOCKS CTL_CODE(FILE_DEVICE_DISK, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_PERFORMANCE CTL_CODE(FILE_DEVICE_DISK, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_IS_WRITABLE CTL_CODE(FILE_DEVICE_DISK, 9, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_LOGGING CTL_CODE(FILE_DEVICE_DISK, 10, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_FORMAT_TRACKS_EX CTL_CODE(FILE_DEVICE_DISK, 11, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_DATA CTL_CODE(FILE_DEVICE_DISK, 13, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_HISTOGRAM_RESET CTL_CODE(FILE_DEVICE_DISK, 14, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_REQUEST_STRUCTURE CTL_CODE(FILE_DEVICE_DISK, 15, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_DISK_REQUEST_DATA CTL_CODE(FILE_DEVICE_DISK, 16, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
69
reactos/drivers/dd/ide/makefile
Normal file
69
reactos/drivers/dd/ide/makefile
Normal file
@@ -0,0 +1,69 @@
|
||||
# $Id: makefile,v 1.10 1999/12/18 10:17:41 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET=ide
|
||||
|
||||
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET).o
|
||||
- $(RM) $(TARGET).coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) $(TARGET).sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
$(TARGET).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp $(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGET).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
include ../../../rules.mak
|
93
reactos/drivers/dd/ide/partitio.h
Normal file
93
reactos/drivers/dd/ide/partitio.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
*** Partition.h - defines and structs for harddrive partition info
|
||||
***
|
||||
*** 05/30/98 RJJ Created
|
||||
**/
|
||||
|
||||
#ifndef __PARTITION_H
|
||||
#define __PARTITION_H
|
||||
|
||||
#define PARTITION_MAGIC 0xaa55
|
||||
#define PART_MAGIC_OFFSET 0x01fe
|
||||
#define PARTITION_OFFSET 0x01be
|
||||
#define PARTITION_TBL_SIZE 4
|
||||
#define PTCHSToLBA(c, h, s, scnt, hcnt) ((s) & 0x3f) + \
|
||||
(scnt) * ( (h) + (hcnt) * ((c) | (((s) & 0xc0) << 2)))
|
||||
#define PTLBAToCHS(lba, c, h, s, scnt, hcnt) ( \
|
||||
(s) = (lba) % (scnt) + 1, \
|
||||
(lba) /= (scnt), \
|
||||
(h) = (lba) % (hcnt), \
|
||||
(lba) /= (heads), \
|
||||
(c) = (lba) & 0xff, \
|
||||
(s) |= ((lba) >> 2) & 0xc0)
|
||||
|
||||
/* taken from linux fdisk src */
|
||||
typedef enum PartitionTypes {
|
||||
PTEmpty = 0,
|
||||
PTDOS3xPrimary, /* 1 */
|
||||
PTXENIXRoot, /* 2 */
|
||||
PTXENIXUsr, /* 3 */
|
||||
PTOLDDOS16Bit, /* 4 */
|
||||
PTDosExtended, /* 5 */
|
||||
PTDos5xPrimary, /* 6 */
|
||||
PTOS2HPFS, /* 7 */
|
||||
PTAIX, /* 8 */
|
||||
PTAIXBootable, /* 9 */
|
||||
PTOS2BootMgr, /* 10 */
|
||||
PTWin95FAT32,
|
||||
PTWin95FAT32LBA,
|
||||
PTWin95FAT16LBA,
|
||||
PTWin95ExtendedLBA,
|
||||
PTVenix286 = 0x40,
|
||||
PTNovell = 0x51,
|
||||
PTMicroport = 0x52,
|
||||
PTGnuHurd = 0x63,
|
||||
PTNetware286 = 0x64,
|
||||
PTNetware386 = 0x65,
|
||||
PTPCIX = 0x75,
|
||||
PTOldMinix = 0x80,
|
||||
PTMinix = 0x81,
|
||||
PTLinuxSwap = 0x82,
|
||||
PTLinuxExt2 = 0x83,
|
||||
PTAmoeba = 0x93,
|
||||
PTAmoebaBBT = 0x94,
|
||||
PTBSD = 0xa5,
|
||||
PTBSDIFS = 0xb7,
|
||||
PTBSDISwap = 0xb8,
|
||||
PTSyrinx = 0xc7,
|
||||
PTCPM = 0xdb,
|
||||
PTDOSAccess = 0xe1,
|
||||
PTDOSRO = 0xe3,
|
||||
PTDOSSecondary = 0xf2,
|
||||
PTBBT = 0xff
|
||||
} PARTITIONTYPES;
|
||||
|
||||
#define PartitionIsSupported(P) \
|
||||
((P)->PartitionType == PTDOS3xPrimary || \
|
||||
(P)->PartitionType == PTOLDDOS16Bit || \
|
||||
(P)->PartitionType == PTDos5xPrimary || \
|
||||
(P)->PartitionType == PTWin95FAT32 || \
|
||||
(P)->PartitionType == PTWin95FAT32LBA || \
|
||||
(P)->PartitionType == PTWin95FAT16LBA || \
|
||||
(P)->PartitionType == PTLinuxExt2)
|
||||
|
||||
#define PartitionIsExtended(P) \
|
||||
((P)->PartitionType == PTDosExtended)
|
||||
|
||||
typedef struct Partition {
|
||||
unsigned char BootFlags;
|
||||
unsigned char StartingHead;
|
||||
unsigned char StartingSector;
|
||||
unsigned char StartingCylinder;
|
||||
unsigned char PartitionType;
|
||||
unsigned char EndingHead;
|
||||
unsigned char EndingSector;
|
||||
unsigned char EndingCylinder;
|
||||
unsigned int StartingBlock;
|
||||
unsigned int SectorCount;
|
||||
|
||||
} PARTITION;
|
||||
|
||||
#endif // PARTITION_H
|
||||
|
||||
|
4
reactos/drivers/dd/keyboard/.cvsignore
Normal file
4
reactos/drivers/dd/keyboard/.cvsignore
Normal file
@@ -0,0 +1,4 @@
|
||||
base.tmp
|
||||
junk.tmp
|
||||
temp.exp
|
||||
|
732
reactos/drivers/dd/keyboard/keyboard.c
Normal file
732
reactos/drivers/dd/keyboard/keyboard.c
Normal file
@@ -0,0 +1,732 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: services/dd/keyboard/keyboard.c
|
||||
* PURPOSE: Keyboard driver
|
||||
* PROGRAMMER: Victor Kirhenshtein (sauros@iname.com)
|
||||
* Jason Filby (jasonfilby@yahoo.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/mmhal.h>
|
||||
#include <internal/halio.h>
|
||||
#include <string.h>
|
||||
#include <internal/string.h>
|
||||
#include <defines.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/*
|
||||
* Driver data
|
||||
*/
|
||||
|
||||
static KEY_EVENT_RECORD kbdBuffer[KBD_BUFFER_SIZE];
|
||||
static int bufHead,bufTail;
|
||||
static int keysInBuffer;
|
||||
static int extKey;
|
||||
static BYTE ledStatus;
|
||||
static BYTE capsDown,numDown,scrollDown;
|
||||
static DWORD ctrlKeyState;
|
||||
static PKINTERRUPT KbdInterrupt;
|
||||
static KDPC KbdDpc;
|
||||
static BOOLEAN AlreadyOpened = FALSE;
|
||||
|
||||
/*
|
||||
* PURPOSE: Current irp being processed
|
||||
*/
|
||||
static PIRP CurrentIrp;
|
||||
|
||||
/*
|
||||
* PURPOSE: Number of keys that have been read into the current irp's buffer
|
||||
*/
|
||||
static ULONG KeysRead;
|
||||
static ULONG KeysRequired;
|
||||
|
||||
/*
|
||||
* Virtual key codes table
|
||||
*
|
||||
* Comments:
|
||||
* * PrtSc = VK_PRINT
|
||||
* * Alt+PrtSc (SysRq) = VK_EXECUTE
|
||||
* * Alt = VK_MENU
|
||||
*/
|
||||
|
||||
static const WORD vkTable[128]=
|
||||
{
|
||||
/* 00 - 07 */ 0, VK_ESCAPE, VK_1, VK_2, VK_3, VK_4, VK_5, VK_6,
|
||||
/* 08 - 0F */ VK_7, VK_8, VK_9, VK_0, 189, 187, VK_BACK, VK_TAB,
|
||||
/* 10 - 17 */ VK_Q, VK_W, VK_E, VK_R, VK_T, VK_Y, VK_U, VK_I,
|
||||
/* 18 - 1F */ VK_O, VK_P, 219, 221, VK_RETURN, VK_CONTROL, VK_A, VK_S,
|
||||
/* 20 - 27 */ VK_D, VK_F, VK_G, VK_H, VK_J, VK_K, VK_L, 186,
|
||||
/* 28 - 2F */ 222, 192, VK_SHIFT, 220, VK_Z, VK_X, VK_C, VK_V,
|
||||
/* 30 - 37 */ VK_B, VK_N, VK_M, 188, 190, 191, VK_SHIFT, VK_MULTIPLY,
|
||||
/* 38 - 3F */ VK_MENU, VK_SPACE, VK_CAPITAL, VK_F1, VK_F2, VK_F3, VK_F4, VK_F5,
|
||||
/* 40 - 47 */ VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, VK_NUMLOCK, VK_SCROLL, VK_HOME,
|
||||
/* 48 - 4F */ VK_UP, VK_PRIOR, VK_SUBTRACT, VK_LEFT, VK_CLEAR, VK_RIGHT, VK_ADD, VK_END,
|
||||
/* 50 - 57 */ VK_DOWN, VK_NEXT, VK_INSERT, VK_DELETE, VK_EXECUTE, 0, 0, VK_F11,
|
||||
/* 58 - 5F */ VK_F12, 0, 0, 91, 92, 93, 0, 0,
|
||||
/* 60 - 67 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 68 - 6F */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 70 - 77 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 78 - 7F */ 0, 0, 0, 0, 0, 0, 0, VK_PAUSE
|
||||
};
|
||||
static const WORD vkKeypadTable[13]= /* 47 - 53 */
|
||||
{
|
||||
VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_SUBTRACT,
|
||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_ADD,
|
||||
VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD0, VK_DECIMAL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ASCII translation tables
|
||||
*/
|
||||
|
||||
static const BYTE asciiTable1[10]=
|
||||
{
|
||||
')','!','@','#','$','%','^','&','*','('
|
||||
};
|
||||
static const BYTE asciiTable2[16]=
|
||||
{
|
||||
'0','1','2','3','4','5','6','7','8','9','*','+',0,'-','.','/'
|
||||
};
|
||||
static const BYTE asciiTable3[37]=
|
||||
{
|
||||
';','=',',','-','.','/','`', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'[', '\\', ']', '\''
|
||||
};
|
||||
static const BYTE asciiTable4[37]=
|
||||
{
|
||||
':','+','<','_','>','?','~', 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
'{', '|', '}', '"'
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static void KbdWrite(int addr,BYTE data)
|
||||
/*
|
||||
* FUNCTION: Write data to keyboard
|
||||
*/
|
||||
{
|
||||
BYTE status;
|
||||
|
||||
do
|
||||
{
|
||||
status=inb_p(KBD_CTRL_PORT); // Wait until input buffer empty
|
||||
} while(status & KBD_IBF);
|
||||
outb_p(addr,data);
|
||||
}
|
||||
|
||||
static int KbdReadData(void)
|
||||
/*
|
||||
* FUNCTION: Read data from port 0x60
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
BYTE status,data;
|
||||
|
||||
i=500000;
|
||||
do
|
||||
{
|
||||
status=inb_p(KBD_CTRL_PORT);
|
||||
if (!(status & KBD_OBF)) // Check if data available
|
||||
continue;
|
||||
data=inb_p(KBD_DATA_PORT);
|
||||
if (status & (KBD_GTO | KBD_PERR)) // Check for timeout error
|
||||
continue;
|
||||
return data;
|
||||
} while(--i);
|
||||
return -1; // Timed out
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set keyboard LED's
|
||||
*/
|
||||
|
||||
static void SetKeyboardLEDs(BYTE status)
|
||||
{
|
||||
KbdWrite(KBD_DATA_PORT,0xED);
|
||||
if (KbdReadData()!=KBD_ACK) // Error
|
||||
return;
|
||||
KbdWrite(KBD_DATA_PORT,status);
|
||||
KbdReadData();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process scan code
|
||||
*/
|
||||
|
||||
static void ProcessScanCode(BYTE scanCode,BOOL isDown)
|
||||
{
|
||||
switch(scanCode)
|
||||
{
|
||||
case 0x1D: // Ctrl
|
||||
if (extKey)
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=RIGHT_CTRL_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~RIGHT_CTRL_PRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=LEFT_CTRL_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~LEFT_CTRL_PRESSED;
|
||||
}
|
||||
break;
|
||||
case 0x2A: // Left shift
|
||||
case 0x36: // Right shift
|
||||
if (isDown)
|
||||
ctrlKeyState|=SHIFT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~SHIFT_PRESSED;
|
||||
break;
|
||||
case 0x38: // Alt
|
||||
if (extKey)
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=RIGHT_ALT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~RIGHT_ALT_PRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDown)
|
||||
ctrlKeyState|=LEFT_ALT_PRESSED;
|
||||
else
|
||||
ctrlKeyState&=~LEFT_ALT_PRESSED;
|
||||
}
|
||||
break;
|
||||
case 0x3A: // CapsLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!capsDown)
|
||||
{
|
||||
capsDown=1;
|
||||
if (ctrlKeyState & CAPSLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_CAPS;
|
||||
ctrlKeyState&=~CAPSLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_CAPS;
|
||||
ctrlKeyState|=CAPSLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
capsDown=0;
|
||||
}
|
||||
break;
|
||||
case 0x45: // NumLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!numDown)
|
||||
{
|
||||
numDown=1;
|
||||
if (ctrlKeyState & NUMLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_NUM;
|
||||
ctrlKeyState&=~NUMLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_NUM;
|
||||
ctrlKeyState|=NUMLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
numDown=0;
|
||||
}
|
||||
break;
|
||||
case 0x46: // ScrollLock
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
break;
|
||||
if (isDown)
|
||||
{
|
||||
if (!scrollDown)
|
||||
{
|
||||
scrollDown=1;
|
||||
if (ctrlKeyState & SCROLLLOCK_ON)
|
||||
{
|
||||
ledStatus&=~KBD_LED_SCROLL;
|
||||
ctrlKeyState&=~SCROLLLOCK_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
ledStatus|=KBD_LED_SCROLL;
|
||||
ctrlKeyState|=SCROLLLOCK_ON;
|
||||
}
|
||||
SetKeyboardLEDs(ledStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollDown=0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Translate virtual key code to ASCII
|
||||
*/
|
||||
|
||||
static BYTE VirtualToAscii(WORD keyCode,BOOL isDown)
|
||||
{
|
||||
if ((ctrlKeyState & ALT_PRESSED)&&(ctrlKeyState & CTRL_PRESSED))
|
||||
return 0; // Ctrl+Alt+char always 0
|
||||
if ((!isDown)&&(ctrlKeyState & ALT_PRESSED))
|
||||
return 0; // Alt+char is 0 when key is released
|
||||
|
||||
if (ctrlKeyState & CTRL_PRESSED)
|
||||
{
|
||||
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||
return keyCode-VK_A+1;
|
||||
switch(keyCode)
|
||||
{
|
||||
case VK_SPACE:
|
||||
return ' ';
|
||||
case VK_BACK:
|
||||
return 127;
|
||||
case VK_RETURN:
|
||||
return 10;
|
||||
case 219: /* [ */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 27;
|
||||
case 220: /* \ */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 28;
|
||||
case 221: /* ] */
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return 0;
|
||||
return 29;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_A)&&(keyCode<=VK_Z))
|
||||
{
|
||||
if (ctrlKeyState & CAPSLOCK_ON)
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return keyCode-VK_A+'a';
|
||||
else
|
||||
return keyCode-VK_A+'A';
|
||||
else
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return keyCode-VK_A+'A';
|
||||
else
|
||||
return keyCode-VK_A+'a';
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_0)&&(keyCode<=VK_9))
|
||||
{
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return asciiTable1[keyCode-VK_0];
|
||||
else
|
||||
return keyCode-VK_0+'0';
|
||||
}
|
||||
|
||||
if ((keyCode>=VK_NUMPAD0)&&(keyCode<=VK_DIVIDE))
|
||||
return asciiTable2[keyCode-VK_NUMPAD0];
|
||||
|
||||
if ((keyCode>=186)&&(keyCode<=222))
|
||||
{
|
||||
if (ctrlKeyState & SHIFT_PRESSED)
|
||||
return asciiTable4[keyCode-186];
|
||||
else
|
||||
return asciiTable3[keyCode-186];
|
||||
}
|
||||
|
||||
switch(keyCode)
|
||||
{
|
||||
case VK_SPACE:
|
||||
return ' ';
|
||||
case VK_RETURN:
|
||||
return '\n';
|
||||
case VK_BACK:
|
||||
return 8;
|
||||
case VK_TAB:
|
||||
return 9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Translate scan code to virtual key code
|
||||
*/
|
||||
|
||||
static WORD ScanToVirtual(BYTE scanCode)
|
||||
{
|
||||
if ((scanCode>=0x47)&&(scanCode<=0x53)&&(ctrlKeyState & NUMLOCK_ON)&&
|
||||
(!extKey)&&(!(ctrlKeyState & SHIFT_PRESSED)))
|
||||
return vkKeypadTable[scanCode-0x47];
|
||||
if ((scanCode==0x35)&&(extKey)) // Gray divide
|
||||
return VK_DIVIDE;
|
||||
if ((scanCode==0x37)&&(extKey)) // Print screen
|
||||
return VK_PRINT;
|
||||
return vkTable[scanCode];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard IRQ handler
|
||||
*/
|
||||
|
||||
static VOID KbdDpcRoutine(PKDPC Dpc,
|
||||
PVOID DeferredContext,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
{
|
||||
PIRP Irp = (PIRP)SystemArgument2;
|
||||
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument1;
|
||||
|
||||
CHECKPOINT;
|
||||
DPRINT("KbdDpcRoutine(DeviceObject %x, Irp %x)\n",
|
||||
DeviceObject,Irp);
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
IoStartNextPacket(DeviceObject,FALSE);
|
||||
}
|
||||
|
||||
static BOOLEAN KeyboardHandler(PKINTERRUPT Interrupt, PVOID Context)
|
||||
{
|
||||
BYTE thisKey;
|
||||
BOOL isDown;
|
||||
static BYTE lastKey;
|
||||
|
||||
CHECKPOINT;
|
||||
|
||||
// Read scan code
|
||||
thisKey=inb_p(KBD_DATA_PORT);
|
||||
if ((thisKey==0xE0)||(thisKey==0xE1)) // Extended key
|
||||
{
|
||||
extKey=1; // Wait for next byte
|
||||
lastKey=thisKey;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
isDown=!(thisKey & 0x80);
|
||||
thisKey&=0x7F;
|
||||
|
||||
// The keyboard maintains its own internal caps lock and num lock
|
||||
// statuses. In caps lock mode E0 AA precedes make code and
|
||||
// E0 2A follow break code. In num lock mode, E0 2A precedes
|
||||
// make code and E0 AA follow break code. We maintain our own caps lock
|
||||
// and num lock statuses, so we will just ignore these.
|
||||
// Some keyboards have L-Shift/R-Shift modes instead of caps lock
|
||||
// mode. If right shift pressed, E0 B6 / E0 36 pairs generated.
|
||||
if (extKey & ((thisKey==0x2A)||(thisKey==0x36)))
|
||||
{
|
||||
extKey=0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check for PAUSE sequence
|
||||
if (extKey && (lastKey==0xE1))
|
||||
{
|
||||
if (thisKey==0x1D)
|
||||
lastKey=0xFF; // Sequence is OK
|
||||
else
|
||||
extKey=0;
|
||||
return FALSE;
|
||||
}
|
||||
if (extKey && (lastKey==0xFF))
|
||||
{
|
||||
if (thisKey!=0x45)
|
||||
{
|
||||
extKey=0; // Bad sequence
|
||||
return FALSE;
|
||||
}
|
||||
thisKey=0x7F; // Pseudo-code for PAUSE
|
||||
}
|
||||
|
||||
ProcessScanCode(thisKey,isDown);
|
||||
|
||||
// DbgPrint("Key: %c\n",VirtualToAscii(ScanToVirtual(thisKey),isDown));
|
||||
// DbgPrint("Key: %x\n",ScanToVirtual(thisKey));
|
||||
if (ScanToVirtual(thisKey)==0x2a)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
if (CurrentIrp!=NULL)
|
||||
{
|
||||
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)
|
||||
CurrentIrp->AssociatedIrp.SystemBuffer;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(CurrentIrp);
|
||||
|
||||
CHECKPOINT;
|
||||
|
||||
rec[KeysRead].bKeyDown=isDown;
|
||||
rec[KeysRead].wRepeatCount=1;
|
||||
rec[KeysRead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||
rec[KeysRead].wVirtualScanCode=thisKey;
|
||||
rec[KeysRead].uChar.AsciiChar=VirtualToAscii(rec->wVirtualKeyCode,isDown);
|
||||
rec[KeysRead].dwControlKeyState=ctrlKeyState;
|
||||
if (extKey)
|
||||
{
|
||||
rec[KeysRead].dwControlKeyState|=ENHANCED_KEY;
|
||||
}
|
||||
KeysRead++;
|
||||
DPRINT("KeysRequired %d KeysRead %x\n",KeysRequired,KeysRead);
|
||||
if (KeysRead==KeysRequired)
|
||||
{
|
||||
KeInsertQueueDpc(&KbdDpc,stk->DeviceObject,CurrentIrp);
|
||||
CurrentIrp=NULL;
|
||||
}
|
||||
CHECKPOINT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Buffer is full ?
|
||||
if (keysInBuffer==KBD_BUFFER_SIZE) // Buffer is full
|
||||
{
|
||||
extKey=0;
|
||||
return(TRUE);
|
||||
}
|
||||
kbdBuffer[bufHead].bKeyDown=isDown;
|
||||
kbdBuffer[bufHead].wRepeatCount=1;
|
||||
kbdBuffer[bufHead].wVirtualKeyCode=ScanToVirtual(thisKey);
|
||||
kbdBuffer[bufHead].wVirtualScanCode=thisKey;
|
||||
kbdBuffer[bufHead].uChar.UnicodeChar=0;
|
||||
// kbdBuffer[bufHead].uChar.AsciiChar=TranslateScanCode(thisKey);
|
||||
kbdBuffer[bufHead].uChar.AsciiChar=VirtualToAscii(kbdBuffer[bufHead].wVirtualKeyCode,isDown);
|
||||
kbdBuffer[bufHead].dwControlKeyState=ctrlKeyState;
|
||||
if (extKey)
|
||||
kbdBuffer[bufHead].dwControlKeyState|=ENHANCED_KEY;
|
||||
bufHead++;
|
||||
bufHead&=KBD_WRAP_MASK; // Modulo KBD_BUFFER_SIZE
|
||||
keysInBuffer++;
|
||||
extKey=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Initialize keyboard
|
||||
//
|
||||
static void KeyboardConnectInterrupt(void)
|
||||
{
|
||||
ULONG MappedIrq;
|
||||
KIRQL Dirql;
|
||||
KAFFINITY Affinity;
|
||||
NTSTATUS Status;
|
||||
|
||||
MappedIrq = HalGetInterruptVector(Internal,
|
||||
0,
|
||||
0,
|
||||
KEYBOARD_IRQ,
|
||||
&Dirql,
|
||||
&Affinity);
|
||||
Status = IoConnectInterrupt(&KbdInterrupt,
|
||||
KeyboardHandler,
|
||||
NULL,
|
||||
NULL,
|
||||
MappedIrq,
|
||||
Dirql,
|
||||
Dirql,
|
||||
0,
|
||||
FALSE,
|
||||
Affinity,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
static int InitializeKeyboard(void)
|
||||
{
|
||||
// Initialize variables
|
||||
bufHead=0;
|
||||
bufTail=0;
|
||||
keysInBuffer=0;
|
||||
ledStatus=0;
|
||||
capsDown=0;
|
||||
numDown=0;
|
||||
scrollDown=0;
|
||||
ctrlKeyState=0;
|
||||
extKey=0;
|
||||
|
||||
KeyboardConnectInterrupt();
|
||||
KeInitializeDpc(&KbdDpc,KbdDpcRoutine,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read data from keyboard buffer
|
||||
*/
|
||||
BOOLEAN KbdSynchronizeRoutine(PVOID Context)
|
||||
{
|
||||
PIRP Irp = (PIRP)Context;
|
||||
KEY_EVENT_RECORD* rec = (KEY_EVENT_RECORD *)Irp->AssociatedIrp.SystemBuffer;
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
ULONG NrToRead = stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||
int i;
|
||||
|
||||
DPRINT("NrToRead %d keysInBuffer %d\n",NrToRead,keysInBuffer);
|
||||
NrToRead = min(NrToRead,keysInBuffer);
|
||||
|
||||
DPRINT("NrToRead %d stk->Parameters.Read.Length %d\n",
|
||||
NrToRead,stk->Parameters.Read.Length);
|
||||
DPRINT("sizeof(KEY_EVENT_RECORD) %d\n",sizeof(KEY_EVENT_RECORD));
|
||||
for (i=0;i<NrToRead;i++)
|
||||
{
|
||||
memcpy(&rec[i],&kbdBuffer[bufTail],sizeof(KEY_EVENT_RECORD));
|
||||
bufTail++;
|
||||
bufTail&=KBD_WRAP_MASK;
|
||||
keysInBuffer--;
|
||||
}
|
||||
if ((stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD))==NrToRead)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
KeysRequired=stk->Parameters.Read.Length/sizeof(KEY_EVENT_RECORD);
|
||||
KeysRead=NrToRead;
|
||||
CurrentIrp=Irp;
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
VOID KbdStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
#endif
|
||||
|
||||
DPRINT("KeyboardStartIo(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||||
|
||||
if (KeSynchronizeExecution(KbdInterrupt, KbdSynchronizeRoutine, Irp))
|
||||
{
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
IoStartNextPacket(DeviceObject, FALSE);
|
||||
}
|
||||
|
||||
DPRINT("stk->Parameters.Read.Length %d\n",stk->Parameters.Read.Length);
|
||||
DPRINT("KeysRequired %d\n",KeysRequired);
|
||||
}
|
||||
|
||||
NTSTATUS KbdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("DeviceObject %x\n",DeviceObject);
|
||||
DPRINT("Irp %x\n",Irp);
|
||||
|
||||
DPRINT("IRP_MJ_CREATE %d stk->MajorFunction %d\n",
|
||||
IRP_MJ_CREATE, stk->MajorFunction);
|
||||
DPRINT("AlreadyOpened %d\n",AlreadyOpened);
|
||||
|
||||
switch (stk->MajorFunction)
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
if (AlreadyOpened == TRUE)
|
||||
{
|
||||
CHECKPOINT;
|
||||
// Status = STATUS_UNSUCCESSFUL;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECKPOINT;
|
||||
Status = STATUS_SUCCESS;
|
||||
AlreadyOpened = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_READ:
|
||||
DPRINT("Handling Read request\n");
|
||||
DPRINT("Queueing packet\n");
|
||||
IoStartPacket(DeviceObject,Irp,NULL,NULL);
|
||||
Status = STATUS_PENDING;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Status==STATUS_PENDING)
|
||||
{
|
||||
DPRINT("Marking irp pending\n");
|
||||
IoMarkIrpPending(Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||||
}
|
||||
DPRINT("Status %d\n",Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||
PUNICODE_STRING RegistryPath)
|
||||
/*
|
||||
* FUNCTION: Module entry point
|
||||
*/
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING SymlinkName;
|
||||
|
||||
DbgPrint("Keyboard Driver 0.0.4\n");
|
||||
InitializeKeyboard();
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = KbdDispatch;
|
||||
DriverObject->DriverStartIo = KbdStartIo;
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Keyboard");
|
||||
IoCreateDevice(DriverObject,
|
||||
0,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_KEYBOARD,
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
RtlInitUnicodeString(&SymlinkName, L"\\??\\Keyboard");
|
||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
67
reactos/drivers/dd/keyboard/keyboard.h
Normal file
67
reactos/drivers/dd/keyboard/keyboard.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Some defines
|
||||
*/
|
||||
|
||||
#define KEYBOARD_IRQ 1
|
||||
#define KBD_BUFFER_SIZE 32
|
||||
#define KBD_WRAP_MASK 0x1F
|
||||
|
||||
#define disable() __asm__("cli\n\t")
|
||||
#define enable() __asm__("sti\n\t")
|
||||
|
||||
#define ALT_PRESSED (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)
|
||||
#define CTRL_PRESSED (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard controller ports
|
||||
*/
|
||||
|
||||
#define KBD_DATA_PORT 0x60
|
||||
#define KBD_CTRL_PORT 0x64
|
||||
|
||||
|
||||
/*
|
||||
* Controller commands
|
||||
*/
|
||||
|
||||
#define KBD_READ_MODE 0x20
|
||||
#define KBD_WRITE_MODE 0x60
|
||||
#define KBD_SELF_TEST 0xAA
|
||||
#define KBD_LINE_TEST 0xAB
|
||||
#define KBD_CTRL_ENABLE 0xAE
|
||||
|
||||
/*
|
||||
* Keyboard commands
|
||||
*/
|
||||
|
||||
#define KBD_ENABLE 0xF4
|
||||
#define KBD_DISABLE 0xF5
|
||||
#define KBD_RESET 0xFF
|
||||
|
||||
|
||||
/*
|
||||
* Keyboard responces
|
||||
*/
|
||||
|
||||
#define KBD_ACK 0xFA
|
||||
#define KBD_BATCC 0xAA
|
||||
|
||||
|
||||
/*
|
||||
* Controller status register bits
|
||||
*/
|
||||
|
||||
#define KBD_OBF 0x01
|
||||
#define KBD_IBF 0x02
|
||||
#define KBD_GTO 0x40
|
||||
#define KBD_PERR 0x80
|
||||
|
||||
|
||||
/*
|
||||
* LED bits
|
||||
*/
|
||||
|
||||
#define KBD_LED_SCROLL 0x01
|
||||
#define KBD_LED_NUM 0x02
|
||||
#define KBD_LED_CAPS 0x04
|
39
reactos/drivers/dd/keyboard/keyboard.rc
Normal file
39
reactos/drivers/dd/keyboard/keyboard.rc
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
|
||||
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "Keyboard Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.4\0"
|
||||
VALUE "InternalName", "keyboard\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "keyboard.sys\0"
|
||||
VALUE "ProductName", RES_STR_PRODUCT_NAME
|
||||
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
70
reactos/drivers/dd/keyboard/makefile
Normal file
70
reactos/drivers/dd/keyboard/makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
# $Id: makefile,v 1.8 1999/12/18 10:17:42 ea Exp $
|
||||
#
|
||||
#
|
||||
TARGET=keyboard
|
||||
|
||||
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
|
||||
|
||||
BASE_CFLAGS = -I../../../include
|
||||
|
||||
all: $(TARGET).sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) $(TARGET).o
|
||||
- $(RM) $(TARGET).coff
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) $(TARGET).sys
|
||||
|
||||
.phony: clean
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
|
||||
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
|
||||
else
|
||||
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
|
||||
endif
|
||||
|
||||
$(TARGET).sys: $(OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp \
|
||||
$(OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname $(TARGET).sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../svc_specs \
|
||||
-mdll \
|
||||
-o $(TARGET).sys \
|
||||
$(OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
include ../../../rules.mak
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user