-#include <ddk/ntddk.h>\r
-#include <stdarg.h>\r
-#include <string.h>\r
-\r
-\r
-void main()\r
-{ \r
- NtDisplayString("Hello world\n");\r
- ExitProcess(0);\r
-}\r
+#include <ddk/ntddk.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+void main()
+{
+ NtDisplayString("Hello world\n");
+ ExitProcess(0);
+}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: services/fs/vfat/blockdev.c\r
- * PURPOSE: Temporary sector reading support\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY: \r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/string.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-#include "ext2fs.h"\r
-\r
-/* FUNCTIONS ***************************************************************/\r
-\r
-BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,\r
- IN ULONG DiskSector,\r
- IN ULONG SectorCount,\r
- IN PVOID Buffer)\r
-{\r
- LARGE_INTEGER sectorNumber;\r
- PIRP irp;\r
- IO_STATUS_BLOCK ioStatus;\r
- KEVENT event;\r
- NTSTATUS status;\r
- ULONG sectorSize;\r
- int j;\r
- \r
- DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",\r
- pDeviceObject,DiskSector,Buffer);\r
-\r
- SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);\r
- SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);\r
-\r
-DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n", \r
- (unsigned long) DiskSector,\r
- (unsigned long) BLOCKSIZE,\r
- (unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),\r
- (unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));\r
-\r
- KeInitializeEvent(&event, NotificationEvent, FALSE);\r
-\r
- sectorSize = BLOCKSIZE*SectorCount;\r
-\r
-\r
- DPRINT("Building synchronous FSD Request...\n");\r
- irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,\r
- pDeviceObject,\r
- Buffer,\r
- sectorSize,\r
- §orNumber,\r
- &event,\r
- &ioStatus );\r
-\r
- if (!irp) {\r
- DbgPrint("READ failed!!!\n");\r
- return FALSE;\r
- }\r
-\r
- DPRINT("Calling IO Driver...\n");\r
- status = IoCallDriver(pDeviceObject,\r
- irp);\r
-\r
- DPRINT("Waiting for IO Operation...\n");\r
- if (status == STATUS_PENDING) {\r
- KeWaitForSingleObject(&event,\r
- Suspended,\r
- KernelMode,\r
- FALSE,\r
- NULL);\r
- DPRINT("Getting IO Status...\n");\r
- status = ioStatus.Status;\r
- }\r
-\r
- if (!NT_SUCCESS(status)) {\r
- DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);\r
- return FALSE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,\r
- IN ULONG DiskSector,\r
- IN ULONG SectorCount,\r
- IN UCHAR* Buffer)\r
-{\r
- LARGE_INTEGER sectorNumber;\r
- PIRP irp;\r
- IO_STATUS_BLOCK ioStatus;\r
- KEVENT event;\r
- NTSTATUS status;\r
- ULONG sectorSize;\r
- PULONG mbr;\r
- int j;\r
- \r
- DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",\r
- pDeviceObject,DiskSector,Buffer);\r
-\r
- SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);\r
- SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);\r
-\r
- KeInitializeEvent(&event, NotificationEvent, FALSE);\r
-\r
- sectorSize = BLOCKSIZE*SectorCount;\r
-\r
-\r
- DPRINT("Building synchronous FSD Request...\n");\r
- irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,\r
- pDeviceObject,\r
- Buffer,\r
- sectorSize,\r
- §orNumber,\r
- &event,\r
- &ioStatus );\r
-\r
- if (!irp) {\r
- DbgPrint("WRITE failed!!!\n");\r
- return FALSE;\r
- }\r
-\r
- DPRINT("Calling IO Driver...\n");\r
- status = IoCallDriver(pDeviceObject,\r
- irp);\r
-\r
- DPRINT("Waiting for IO Operation...\n");\r
- if (status == STATUS_PENDING) {\r
- KeWaitForSingleObject(&event,\r
- Suspended,\r
- KernelMode,\r
- FALSE,\r
- NULL);\r
- DPRINT("Getting IO Status...\n");\r
- status = ioStatus.Status;\r
- }\r
-\r
- if (!NT_SUCCESS(status)) {\r
- DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);\r
- return FALSE;\r
- }\r
-\r
-\r
- ExFreePool(mbr);\r
- DPRINT("Block request succeeded\n");\r
- return TRUE;\r
-}\r
-\r
-\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/vfat/blockdev.c
+ * PURPOSE: Temporary sector reading support
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/string.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#include "ext2fs.h"
+
+/* FUNCTIONS ***************************************************************/
+
+BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
+ IN ULONG DiskSector,
+ IN ULONG SectorCount,
+ IN PVOID Buffer)
+{
+ LARGE_INTEGER sectorNumber;
+ PIRP irp;
+ IO_STATUS_BLOCK ioStatus;
+ KEVENT event;
+ NTSTATUS status;
+ ULONG sectorSize;
+ int j;
+
+ DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
+ pDeviceObject,DiskSector,Buffer);
+
+ SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
+ SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
+
+DPRINT("DiskSector:%ld BLKSZ:%ld sectorNumber:%ld:%ld\n",
+ (unsigned long) DiskSector,
+ (unsigned long) BLOCKSIZE,
+ (unsigned long) GET_LARGE_INTEGER_HIGH_PART(sectorNumber),
+ (unsigned long) GET_LARGE_INTEGER_LOW_PART(sectorNumber));
+
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+
+ sectorSize = BLOCKSIZE*SectorCount;
+
+
+ DPRINT("Building synchronous FSD Request...\n");
+ irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ pDeviceObject,
+ Buffer,
+ sectorSize,
+ §orNumber,
+ &event,
+ &ioStatus );
+
+ if (!irp) {
+ DbgPrint("READ failed!!!\n");
+ return FALSE;
+ }
+
+ DPRINT("Calling IO Driver...\n");
+ status = IoCallDriver(pDeviceObject,
+ irp);
+
+ DPRINT("Waiting for IO Operation...\n");
+ if (status == STATUS_PENDING) {
+ KeWaitForSingleObject(&event,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL);
+ DPRINT("Getting IO Status...\n");
+ status = ioStatus.Status;
+ }
+
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
+ IN ULONG DiskSector,
+ IN ULONG SectorCount,
+ IN UCHAR* Buffer)
+{
+ LARGE_INTEGER sectorNumber;
+ PIRP irp;
+ IO_STATUS_BLOCK ioStatus;
+ KEVENT event;
+ NTSTATUS status;
+ ULONG sectorSize;
+ PULONG mbr;
+ int j;
+
+ DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
+ pDeviceObject,DiskSector,Buffer);
+
+ SET_LARGE_INTEGER_HIGH_PART(sectorNumber, 0);
+ SET_LARGE_INTEGER_LOW_PART(sectorNumber, DiskSector * BLOCKSIZE);
+
+ KeInitializeEvent(&event, NotificationEvent, FALSE);
+
+ sectorSize = BLOCKSIZE*SectorCount;
+
+
+ DPRINT("Building synchronous FSD Request...\n");
+ irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+ pDeviceObject,
+ Buffer,
+ sectorSize,
+ §orNumber,
+ &event,
+ &ioStatus );
+
+ if (!irp) {
+ DbgPrint("WRITE failed!!!\n");
+ return FALSE;
+ }
+
+ DPRINT("Calling IO Driver...\n");
+ status = IoCallDriver(pDeviceObject,
+ irp);
+
+ DPRINT("Waiting for IO Operation...\n");
+ if (status == STATUS_PENDING) {
+ KeWaitForSingleObject(&event,
+ Suspended,
+ KernelMode,
+ FALSE,
+ NULL);
+ DPRINT("Getting IO Status...\n");
+ status = ioStatus.Status;
+ }
+
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("IO failed!!! Error code: %d(%x)\n", status, status);
+ return FALSE;
+ }
+
+
+ ExFreePool(mbr);
+ DPRINT("Block request succeeded\n");
+ return TRUE;
+}
+
+
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: services/fs/ext2/super.c\r
- * PURPOSE: ext2 filesystem\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY: \r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/string.h>\r
-#include <wstring.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-#include "ext2fs.h"\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)\r
-{\r
- ULONG i;\r
- \r
- for (i=0; i<Len; i++)\r
- {\r
- *Out = *In;\r
- Out++;\r
- In++;\r
- }\r
- *Out = 0;\r
-}\r
-\r
-PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,\r
- struct ext2_dir_entry* dir_entry,\r
- PIO_STACK_LOCATION IoStack,\r
- PVOID Buffer,\r
- ULONG FileIndex)\r
-{\r
- PFILE_DIRECTORY_INFORMATION FDI;\r
- PFILE_NAMES_INFORMATION FNI;\r
- ULONG i;\r
- PWSTR FileName;\r
- struct ext2_inode inode;\r
- \r
- Ext2ReadInode(DeviceExt,\r
- dir_entry->inode,\r
- &inode);\r
- \r
- switch (IoStack->Parameters.QueryDirectory.FileInformationClass)\r
- {\r
- case FileNamesInformation:\r
- FNI = (PFILE_NAMES_INFORMATION)Buffer;\r
- FNI->NextEntryOffset = sizeof(FileDirectoryInformation) +\r
- dir_entry->name_len + 1;\r
- FNI->FileNameLength = dir_entry->name_len; \r
- Ext2ConvertName(FNI->FileName, dir_entry->name, dir_entry->name_len);\r
- Buffer = Buffer + FNI->NextEntryOffset;\r
- break;\r
- \r
- case FileDirectoryInformation:\r
- FDI = (PFILE_DIRECTORY_INFORMATION)Buffer;\r
- FDI->NextEntryOffset = sizeof(FileDirectoryInformation) + \r
- dir_entry->name_len + 1;\r
- FDI->FileIndex = FileIndex;\r
-// FDI->CreationTime = 0;\r
-// FDI->LastAccessTime = 0;\r
-// FDI->LastWriteTime = 0;\r
-// FDI->ChangeTime = 0;\r
- FDI->AllocationSize = FDI->EndOfFile = inode.i_size;\r
- FDI->FileAttributes = 0;\r
- FDI->FileNameLength = dir_entry->name_len;\r
- Ext2ConvertName(FDI->FileName, dir_entry->name, dir_entry->name_len);\r
- Buffer = Buffer + FDI->NextEntryOffset;\r
- break;\r
- \r
- default:\r
- UNIMPLEMENTED;\r
- }\r
- return(Buffer);\r
-}\r
- \r
-\r
-NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,\r
- PEXT2_FCB Fcb,\r
- PIRP Irp,\r
- PIO_STACK_LOCATION IoStack)\r
-{\r
- ULONG Max;\r
- ULONG i;\r
- ULONG StartIndex;\r
- PVOID Buffer;\r
- struct ext2_dir_entry dir_entry;\r
- ULONG CurrentIndex;\r
- \r
- Buffer = Irp->UserBuffer;\r
- \r
- if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)\r
- {\r
- Max = 1;\r
- }\r
- else\r
- {\r
- UNIMPLEMENTED;\r
- }\r
- \r
- if (IoStack->Flags & SL_INDEX_SPECIFIED)\r
- {\r
- StartIndex = ((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex;\r
- }\r
- else\r
- {\r
- StartIndex = 0;\r
- }\r
- \r
- if (IoStack->Flags & SL_RESTART_SCAN)\r
- {\r
- StartIndex = 0;\r
- }\r
- \r
- for (i=0; i<Max ;i++)\r
- {\r
- if (!Ext2ScanDir(DeviceExt,&Fcb->inode,"*",&dir_entry,&StartIndex)) \r
- {\r
- ((PFILE_DIRECTORY_INFORMATION)Buffer)->NextEntryOffset = 0;\r
- return(STATUS_NO_MORE_FILES);\r
- }\r
- Buffer = Ext2ProcessDirEntry(DeviceExt,\r
- &dir_entry, \r
- IoStack, \r
- Buffer, \r
- StartIndex);\r
- }\r
-}\r
-\r
-NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);\r
- PFILE_OBJECT FileObject = Stack->FileObject;\r
- PEXT2_FCB Fcb = (PVOID)FileObject->FsContext;\r
- NTSTATUS Status;\r
- PDEVICE_EXTENSION DeviceExt;\r
- \r
- DPRINT("Ext2DirectoryControl(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);\r
- \r
- DeviceExt = DeviceObject->DeviceExtension;\r
- \r
- switch (Stack->MinorFunction)\r
- {\r
- case IRP_MN_QUERY_DIRECTORY:\r
- Status = Ext2QueryDirectory(DeviceExt, Fcb, Irp, Stack);\r
- break;\r
- \r
- default:\r
- Status = STATUS_UNSUCCESSFUL;\r
- }\r
- \r
- Irp->IoStatus.Status = Status;\r
- Irp->IoStatus.Information = 0;\r
- \r
- IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
- return(Status); \r
-}\r
-\r
-BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,\r
- struct ext2_inode* dir, \r
- PCH filename,\r
- struct ext2_dir_entry* ret,\r
- PULONG StartIndex)\r
-{\r
- ULONG i;\r
- char* buffer;\r
- ULONG offset;\r
- char name[255];\r
- struct ext2_dir_entry* current;\r
- ULONG block;\r
- \r
- DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);\r
- \r
- buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);\r
- \r
- for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);\r
- for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)\r
- {\r
- DPRINT("block %d\n",block);\r
- Ext2ReadSectors(DeviceExt->StorageDevice,\r
- block,\r
- 1,\r
- buffer);\r
- \r
- offset = (*StartIndex)%BLOCKSIZE;\r
- while (offset < BLOCKSIZE)\r
- {\r
- current = &buffer[offset];\r
- \r
- strncpy(name,current->name,current->name_len);\r
- name[current->name_len]=0;\r
- \r
- DPRINT("Scanning offset %d inode %d name %s\n",\r
- offset,current->inode,name);\r
-\r
- DPRINT("Comparing %s %s\n",name,filename);\r
- if (strcmp(name,filename)==0 || strcmp(filename,"*")==0)\r
- {\r
- DPRINT("Match found\n");\r
- *StartIndex = (i*BLOCKSIZE) + offset + current->rec_len;\r
- memcpy(ret,current,sizeof(struct ext2_dir_entry));\r
- ExFreePool(buffer);\r
- return(TRUE);\r
- }\r
- \r
- offset = offset + current->rec_len;\r
- assert(current->rec_len != 0);\r
- DPRINT("offset %d\n",offset);\r
- }\r
- DPRINT("Onto next block\n");\r
- }\r
- DPRINT("No match\n");\r
- ExFreePool(buffer);\r
- return(FALSE);\r
-}\r
-\r
-void unicode_to_ansi(PCH StringA, PWSTR StringW)\r
-{\r
- while((*StringW)!=0)\r
- {\r
- *StringA = *StringW;\r
- StringA++;\r
- StringW++;\r
- }\r
- *StringA = 0;\r
-}\r
-\r
-NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, \r
- PWSTR FileName)\r
-/*\r
- * FUNCTION: Opens a file\r
- */\r
-{\r
- struct ext2_inode parent_inode;\r
- struct ext2_dir_entry entry;\r
- char name[255];\r
- ULONG current_inode = 2;\r
- char* current_segment;\r
- PEXT2_FCB Fcb;\r
- ULONG StartIndex = 0;\r
- \r
- DPRINT("Ext2OpenFile(DeviceExt %x, FileObject %x, FileName %w)\n",\r
- DeviceExt,FileObject,FileName);\r
- \r
- Fcb = ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));\r
- \r
- unicode_to_ansi(name,FileName);\r
- DbgPrint("name %s\n",name);\r
- \r
- current_segment = strtok(name,"\\");\r
- do\r
- {\r
- Ext2ReadInode(DeviceExt,\r
- current_inode,\r
- &parent_inode);\r
- if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,\r
- &StartIndex))\r
- {\r
- ExFreePool(Fcb);\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- current_inode = entry.inode;\r
- current_segment = strtok(NULL,"\\");\r
- } while(current_segment!=NULL);\r
- DPRINT("Found file\n");\r
- \r
- Ext2ReadInode(DeviceExt,\r
- current_inode,\r
- &Fcb->inode);\r
- FileObject->FsContext = Fcb;\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);\r
- PFILE_OBJECT FileObject = Stack->FileObject;\r
- NTSTATUS Status;\r
- PDEVICE_EXTENSION DeviceExt;\r
- \r
- DPRINT("Ext2Create(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);\r
- \r
- DeviceExt = DeviceObject->DeviceExtension;\r
- Status = Ext2OpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);\r
- \r
- Irp->IoStatus.Status = Status;\r
- Irp->IoStatus.Information = 0;\r
- \r
- IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
- return(Status);\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/ext2/super.c
+ * PURPOSE: ext2 filesystem
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/string.h>
+#include <wstring.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#include "ext2fs.h"
+
+/* FUNCTIONS *****************************************************************/
+
+VOID Ext2ConvertName(PWSTR Out, PCH In, ULONG Len)
+{
+ ULONG i;
+
+ for (i=0; i<Len; i++)
+ {
+ *Out = *In;
+ Out++;
+ In++;
+ }
+ *Out = 0;
+}
+
+PVOID Ext2ProcessDirEntry(PDEVICE_EXTENSION DeviceExt,
+ struct ext2_dir_entry* dir_entry,
+ PIO_STACK_LOCATION IoStack,
+ PVOID Buffer,
+ ULONG FileIndex)
+{
+ PFILE_DIRECTORY_INFORMATION FDI;
+ PFILE_NAMES_INFORMATION FNI;
+ ULONG i;
+ PWSTR FileName;
+ struct ext2_inode inode;
+
+ Ext2ReadInode(DeviceExt,
+ dir_entry->inode,
+ &inode);
+
+ switch (IoStack->Parameters.QueryDirectory.FileInformationClass)
+ {
+ case FileNamesInformation:
+ FNI = (PFILE_NAMES_INFORMATION)Buffer;
+ FNI->NextEntryOffset = sizeof(FileDirectoryInformation) +
+ dir_entry->name_len + 1;
+ FNI->FileNameLength = dir_entry->name_len;
+ Ext2ConvertName(FNI->FileName, dir_entry->name, dir_entry->name_len);
+ Buffer = Buffer + FNI->NextEntryOffset;
+ break;
+
+ case FileDirectoryInformation:
+ FDI = (PFILE_DIRECTORY_INFORMATION)Buffer;
+ FDI->NextEntryOffset = sizeof(FileDirectoryInformation) +
+ dir_entry->name_len + 1;
+ FDI->FileIndex = FileIndex;
+// FDI->CreationTime = 0;
+// FDI->LastAccessTime = 0;
+// FDI->LastWriteTime = 0;
+// FDI->ChangeTime = 0;
+ FDI->AllocationSize = FDI->EndOfFile = inode.i_size;
+ FDI->FileAttributes = 0;
+ FDI->FileNameLength = dir_entry->name_len;
+ Ext2ConvertName(FDI->FileName, dir_entry->name, dir_entry->name_len);
+ Buffer = Buffer + FDI->NextEntryOffset;
+ break;
+
+ default:
+ UNIMPLEMENTED;
+ }
+ return(Buffer);
+}
+
+
+NTSTATUS Ext2QueryDirectory(PDEVICE_EXTENSION DeviceExt,
+ PEXT2_FCB Fcb,
+ PIRP Irp,
+ PIO_STACK_LOCATION IoStack)
+{
+ ULONG Max;
+ ULONG i;
+ ULONG StartIndex;
+ PVOID Buffer;
+ struct ext2_dir_entry dir_entry;
+ ULONG CurrentIndex;
+
+ Buffer = Irp->UserBuffer;
+
+ if (IoStack->Flags & SL_RETURN_SINGLE_ENTRY)
+ {
+ Max = 1;
+ }
+ else
+ {
+ UNIMPLEMENTED;
+ }
+
+ if (IoStack->Flags & SL_INDEX_SPECIFIED)
+ {
+ StartIndex = ((PFILE_DIRECTORY_INFORMATION)Buffer)->FileIndex;
+ }
+ else
+ {
+ StartIndex = 0;
+ }
+
+ if (IoStack->Flags & SL_RESTART_SCAN)
+ {
+ StartIndex = 0;
+ }
+
+ for (i=0; i<Max ;i++)
+ {
+ if (!Ext2ScanDir(DeviceExt,&Fcb->inode,"*",&dir_entry,&StartIndex))
+ {
+ ((PFILE_DIRECTORY_INFORMATION)Buffer)->NextEntryOffset = 0;
+ return(STATUS_NO_MORE_FILES);
+ }
+ Buffer = Ext2ProcessDirEntry(DeviceExt,
+ &dir_entry,
+ IoStack,
+ Buffer,
+ StartIndex);
+ }
+}
+
+NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PFILE_OBJECT FileObject = Stack->FileObject;
+ PEXT2_FCB Fcb = (PVOID)FileObject->FsContext;
+ NTSTATUS Status;
+ PDEVICE_EXTENSION DeviceExt;
+
+ DPRINT("Ext2DirectoryControl(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+
+ DeviceExt = DeviceObject->DeviceExtension;
+
+ switch (Stack->MinorFunction)
+ {
+ case IRP_MN_QUERY_DIRECTORY:
+ Status = Ext2QueryDirectory(DeviceExt, Fcb, Irp, Stack);
+ break;
+
+ default:
+ Status = STATUS_UNSUCCESSFUL;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+}
+
+BOOL Ext2ScanDir(PDEVICE_EXTENSION DeviceExt,
+ struct ext2_inode* dir,
+ PCH filename,
+ struct ext2_dir_entry* ret,
+ PULONG StartIndex)
+{
+ ULONG i;
+ char* buffer;
+ ULONG offset;
+ char name[255];
+ struct ext2_dir_entry* current;
+ ULONG block;
+
+ DPRINT("Ext2ScanDir(dir %x, filename %s, ret %x)\n",dir,filename,ret);
+
+ buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+
+ for (i=0; i<((*StartIndex)/BLOCKSIZE); i++);
+ for (; (block = Ext2BlockMap(DeviceExt, dir, i)) != 0; i++)
+ {
+ DPRINT("block %d\n",block);
+ Ext2ReadSectors(DeviceExt->StorageDevice,
+ block,
+ 1,
+ buffer);
+
+ offset = (*StartIndex)%BLOCKSIZE;
+ while (offset < BLOCKSIZE)
+ {
+ current = &buffer[offset];
+
+ strncpy(name,current->name,current->name_len);
+ name[current->name_len]=0;
+
+ DPRINT("Scanning offset %d inode %d name %s\n",
+ offset,current->inode,name);
+
+ DPRINT("Comparing %s %s\n",name,filename);
+ if (strcmp(name,filename)==0 || strcmp(filename,"*")==0)
+ {
+ DPRINT("Match found\n");
+ *StartIndex = (i*BLOCKSIZE) + offset + current->rec_len;
+ memcpy(ret,current,sizeof(struct ext2_dir_entry));
+ ExFreePool(buffer);
+ return(TRUE);
+ }
+
+ offset = offset + current->rec_len;
+ assert(current->rec_len != 0);
+ DPRINT("offset %d\n",offset);
+ }
+ DPRINT("Onto next block\n");
+ }
+ DPRINT("No match\n");
+ ExFreePool(buffer);
+ return(FALSE);
+}
+
+void unicode_to_ansi(PCH StringA, PWSTR StringW)
+{
+ while((*StringW)!=0)
+ {
+ *StringA = *StringW;
+ StringA++;
+ StringW++;
+ }
+ *StringA = 0;
+}
+
+NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
+ PWSTR FileName)
+/*
+ * FUNCTION: Opens a file
+ */
+{
+ struct ext2_inode parent_inode;
+ struct ext2_dir_entry entry;
+ char name[255];
+ ULONG current_inode = 2;
+ char* current_segment;
+ PEXT2_FCB Fcb;
+ ULONG StartIndex = 0;
+
+ DPRINT("Ext2OpenFile(DeviceExt %x, FileObject %x, FileName %w)\n",
+ DeviceExt,FileObject,FileName);
+
+ Fcb = ExAllocatePool(NonPagedPool, sizeof(EXT2_FCB));
+
+ unicode_to_ansi(name,FileName);
+ DbgPrint("name %s\n",name);
+
+ current_segment = strtok(name,"\\");
+ do
+ {
+ Ext2ReadInode(DeviceExt,
+ current_inode,
+ &parent_inode);
+ if (!Ext2ScanDir(DeviceExt,&parent_inode,current_segment,&entry,
+ &StartIndex))
+ {
+ ExFreePool(Fcb);
+ return(STATUS_UNSUCCESSFUL);
+ }
+ current_inode = entry.inode;
+ current_segment = strtok(NULL,"\\");
+ } while(current_segment!=NULL);
+ DPRINT("Found file\n");
+
+ Ext2ReadInode(DeviceExt,
+ current_inode,
+ &Fcb->inode);
+ FileObject->FsContext = Fcb;
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PFILE_OBJECT FileObject = Stack->FileObject;
+ NTSTATUS Status;
+ PDEVICE_EXTENSION DeviceExt;
+
+ DPRINT("Ext2Create(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+
+ DeviceExt = DeviceObject->DeviceExtension;
+ Status = Ext2OpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+}
-BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,\r
- IN ULONG DiskSector,\r
- IN ULONG SectorCount,\r
- IN PVOID Buffer);\r
-\r
-#define BLOCKSIZE (1024)\r
-\r
-struct ext2_super_block {\r
- ULONG s_inodes_count; /* Inodes count */\r
- ULONG s_blocks_count; /* Blocks count */\r
- ULONG s_r_blocks_count; /* Reserved blocks count */\r
- ULONG s_free_blocks_count; /* Free blocks count */\r
- ULONG s_free_inodes_count; /* Free inodes count */\r
- ULONG s_first_data_block; /* First Data Block */\r
- ULONG s_log_block_size; /* Block size */\r
- LONG s_log_frag_size; /* Fragment size */\r
- ULONG s_blocks_per_group; /* # Blocks per group */\r
- ULONG s_frags_per_group; /* # Fragments per group */\r
- ULONG s_inodes_per_group; /* # Inodes per group */\r
- ULONG s_mtime; /* Mount time */\r
- ULONG s_wtime; /* Write time */\r
- USHORT s_mnt_count; /* Mount count */\r
- SHORT s_max_mnt_count; /* Maximal mount count */\r
- USHORT s_magic; /* Magic signature */\r
- USHORT s_state; /* File system state */\r
- USHORT s_errors; /* Behaviour when detecting errors */\r
- USHORT s_minor_rev_level; /* minor revision level */\r
- ULONG s_lastcheck; /* time of last check */\r
- ULONG s_checkinterval; /* max. time between checks */\r
- ULONG s_creator_os; /* OS */\r
- ULONG s_rev_level; /* Revision level */\r
- USHORT s_def_resuid; /* Default uid for reserved blocks */\r
- USHORT s_def_resgid; /* Default gid for reserved blocks */\r
- /*\r
- * These fields are for EXT2_DYNAMIC_REV superblocks only.\r
- *\r
- * Note: the difference between the compatible feature set and\r
- * the incompatible feature set is that if there is a bit set\r
- * in the incompatible feature set that the kernel doesn't\r
- * know about, it should refuse to mount the filesystem.\r
- * \r
- * e2fsck's requirements are more strict; if it doesn't know\r
- * about a feature in either the compatible or incompatible\r
- * feature set, it must abort and not try to meddle with\r
- * things it doesn't understand...\r
- */\r
- ULONG s_first_ino; /* First non-reserved inode */\r
- USHORT s_inode_size; /* size of inode structure */\r
- USHORT s_block_group_nr; /* block group # of this superblock */\r
- ULONG s_feature_compat; /* compatible feature set */\r
- ULONG s_feature_incompat; /* incompatible feature set */\r
- ULONG s_feature_ro_compat; /* readonly-compatible feature set */\r
- ULONG s_reserved[230]; /* Padding to the end of the block */\r
-};\r
-\r
-/*\r
- * Codes for operating systems\r
- */\r
-#define EXT2_OS_LINUX 0\r
-#define EXT2_OS_HURD 1\r
-#define EXT2_OS_MASIX 2\r
-#define EXT2_OS_FREEBSD 3\r
-#define EXT2_OS_LITES 4\r
-\r
-/*\r
- * Revision levels\r
- */\r
-#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */\r
-#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */\r
-\r
-#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV\r
-#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV\r
-\r
-/*\r
- * The second extended file system magic number\r
- */\r
-#define EXT2_SUPER_MAGIC 0xEF53\r
-\r
-/*\r
- * Constants relative to the data blocks\r
- */\r
-#define EXT2_NDIR_BLOCKS 12\r
-#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS\r
-#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)\r
-#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)\r
-#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)\r
-\r
-\r
-/*\r
- * Structure of an inode on the disk\r
- */\r
-struct ext2_inode {\r
- USHORT i_mode; /* File mode */\r
- USHORT i_uid; /* Owner Uid */\r
- ULONG i_size; /* Size in bytes */\r
- ULONG i_atime; /* Access time */\r
- ULONG i_ctime; /* Creation time */\r
- ULONG i_mtime; /* Modification time */\r
- ULONG i_dtime; /* Deletion Time */\r
- USHORT i_gid; /* Group Id */\r
- USHORT i_links_count; /* Links count */\r
- ULONG i_blocks; /* Blocks count */\r
- ULONG i_flags; /* File flags */\r
- union {\r
- struct {\r
- ULONG l_i_reserved1;\r
- } linux1;\r
- struct {\r
- ULONG h_i_translator;\r
- } hurd1;\r
- struct {\r
- ULONG m_i_reserved1;\r
- } masix1;\r
- } osd1; /* OS dependent 1 */\r
- ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */\r
- ULONG i_version; /* File version (for NFS) */\r
- ULONG i_file_acl; /* File ACL */\r
- ULONG i_dir_acl; /* Directory ACL */\r
- ULONG i_faddr; /* Fragment address */\r
- union {\r
- struct {\r
- UCHAR l_i_frag; /* Fragment number */\r
- UCHAR l_i_fsize; /* Fragment size */\r
- USHORT i_pad1;\r
- ULONG l_i_reserved2[2];\r
- } linux2;\r
- struct {\r
- UCHAR h_i_frag; /* Fragment number */\r
- UCHAR h_i_fsize; /* Fragment size */\r
- USHORT h_i_mode_high;\r
- USHORT h_i_uid_high;\r
- USHORT h_i_gid_high;\r
- ULONG h_i_author;\r
- } hurd2;\r
- struct {\r
- UCHAR m_i_frag; /* Fragment number */\r
- UCHAR m_i_fsize; /* Fragment size */\r
- USHORT m_pad1;\r
- ULONG m_i_reserved2[2];\r
- } masix2;\r
- } osd2; /* OS dependent 2 */\r
-};\r
-\r
-#if defined(__KERNEL__) || defined(__linux__)\r
-#define i_reserved1 osd1.linux1.l_i_reserved1\r
-#define i_frag osd2.linux2.l_i_frag\r
-#define i_fsize osd2.linux2.l_i_fsize\r
-#define i_reserved2 osd2.linux2.l_i_reserved2\r
-#endif\r
-\r
-#ifdef __hurd__\r
-#define i_translator osd1.hurd1.h_i_translator\r
-#define i_frag osd2.hurd2.h_i_frag;\r
-#define i_fsize osd2.hurd2.h_i_fsize;\r
-#define i_uid_high osd2.hurd2.h_i_uid_high\r
-#define i_gid_high osd2.hurd2.h_i_gid_high\r
-#define i_author osd2.hurd2.h_i_author\r
-#endif\r
-\r
-#ifdef __masix__\r
-#define i_reserved1 osd1.masix1.m_i_reserved1\r
-#define i_frag osd2.masix2.m_i_frag\r
-#define i_fsize osd2.masix2.m_i_fsize\r
-#define i_reserved2 osd2.masix2.m_i_reserved2\r
-#endif\r
-\r
-/*\r
- * Constants relative to the data blocks\r
- */\r
-#define EXT2_NDIR_BLOCKS 12\r
-#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS\r
-#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)\r
-#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)\r
-#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)\r
-\r
-/*\r
- * Inode flags\r
- */\r
-#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */\r
-#define EXT2_UNRM_FL 0x00000002 /* Undelete */\r
-#define EXT2_COMPR_FL 0x00000004 /* Compress file */\r
-#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */\r
-#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */\r
-#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */\r
-#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */\r
-#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */\r
- \r
-\r
-/*\r
- * Structure of a blocks group descriptor\r
- */\r
-struct ext2_group_desc\r
-{\r
- ULONG bg_block_bitmap; /* Blocks bitmap block */\r
- ULONG bg_inode_bitmap; /* Inodes bitmap block */\r
- ULONG bg_inode_table; /* Inodes table block */\r
- USHORT bg_free_blocks_count; /* Free blocks count */\r
- USHORT bg_free_inodes_count; /* Free inodes count */\r
- USHORT bg_used_dirs_count; /* Directories count */\r
- USHORT bg_pad;\r
- ULONG bg_reserved[3];\r
-};\r
-\r
-#define EXT2_NAME_LEN 255\r
-\r
-struct ext2_dir_entry {\r
- ULONG inode; /* Inode number */\r
- USHORT rec_len; /* Directory entry length */\r
- USHORT name_len; /* Name length */\r
- char name[EXT2_NAME_LEN]; /* File name */\r
-};\r
-\r
-typedef struct\r
-{\r
- PDEVICE_OBJECT StorageDevice;\r
- struct ext2_super_block* superblock;\r
-} DEVICE_EXTENSION, *PDEVICE_EXTENSION;\r
-\r
-\r
-VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,\r
- ULONG ino,\r
- struct ext2_inode* inode);\r
-struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,\r
- ULONG block_group);\r
-\r
-typedef struct _EXT2_FCB\r
-{\r
- struct ext2_inode inode;\r
-} EXT2_FCB, *PEXT2_FCB;\r
-\r
-ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,\r
- struct ext2_inode* inode,\r
- ULONG offset);\r
-NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, \r
- PWSTR FileName);\r
-NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt, \r
- PFILE_OBJECT FileObject,\r
- PVOID Buffer, \r
- ULONG Length, \r
- LARGE_INTEGER Offset);\r
-NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);\r
-NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);\r
+BOOLEAN Ext2ReadSectors(IN PDEVICE_OBJECT pDeviceObject,
+ IN ULONG DiskSector,
+ IN ULONG SectorCount,
+ IN PVOID Buffer);
+
+#define BLOCKSIZE (1024)
+
+struct ext2_super_block {
+ ULONG s_inodes_count; /* Inodes count */
+ ULONG s_blocks_count; /* Blocks count */
+ ULONG s_r_blocks_count; /* Reserved blocks count */
+ ULONG s_free_blocks_count; /* Free blocks count */
+ ULONG s_free_inodes_count; /* Free inodes count */
+ ULONG s_first_data_block; /* First Data Block */
+ ULONG s_log_block_size; /* Block size */
+ LONG s_log_frag_size; /* Fragment size */
+ ULONG s_blocks_per_group; /* # Blocks per group */
+ ULONG s_frags_per_group; /* # Fragments per group */
+ ULONG s_inodes_per_group; /* # Inodes per group */
+ ULONG s_mtime; /* Mount time */
+ ULONG s_wtime; /* Write time */
+ USHORT s_mnt_count; /* Mount count */
+ SHORT s_max_mnt_count; /* Maximal mount count */
+ USHORT s_magic; /* Magic signature */
+ USHORT s_state; /* File system state */
+ USHORT s_errors; /* Behaviour when detecting errors */
+ USHORT s_minor_rev_level; /* minor revision level */
+ ULONG s_lastcheck; /* time of last check */
+ ULONG s_checkinterval; /* max. time between checks */
+ ULONG s_creator_os; /* OS */
+ ULONG s_rev_level; /* Revision level */
+ USHORT s_def_resuid; /* Default uid for reserved blocks */
+ USHORT s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ ULONG s_first_ino; /* First non-reserved inode */
+ USHORT s_inode_size; /* size of inode structure */
+ USHORT s_block_group_nr; /* block group # of this superblock */
+ ULONG s_feature_compat; /* compatible feature set */
+ ULONG s_feature_incompat; /* incompatible feature set */
+ ULONG s_feature_ro_compat; /* readonly-compatible feature set */
+ ULONG s_reserved[230]; /* Padding to the end of the block */
+};
+
+/*
+ * Codes for operating systems
+ */
+#define EXT2_OS_LINUX 0
+#define EXT2_OS_HURD 1
+#define EXT2_OS_MASIX 2
+#define EXT2_OS_FREEBSD 3
+#define EXT2_OS_LITES 4
+
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
+#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
+
+/*
+ * The second extended file system magic number
+ */
+#define EXT2_SUPER_MAGIC 0xEF53
+
+/*
+ * Constants relative to the data blocks
+ */
+#define EXT2_NDIR_BLOCKS 12
+#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
+
+/*
+ * Structure of an inode on the disk
+ */
+struct ext2_inode {
+ USHORT i_mode; /* File mode */
+ USHORT i_uid; /* Owner Uid */
+ ULONG i_size; /* Size in bytes */
+ ULONG i_atime; /* Access time */
+ ULONG i_ctime; /* Creation time */
+ ULONG i_mtime; /* Modification time */
+ ULONG i_dtime; /* Deletion Time */
+ USHORT i_gid; /* Group Id */
+ USHORT i_links_count; /* Links count */
+ ULONG i_blocks; /* Blocks count */
+ ULONG i_flags; /* File flags */
+ union {
+ struct {
+ ULONG l_i_reserved1;
+ } linux1;
+ struct {
+ ULONG h_i_translator;
+ } hurd1;
+ struct {
+ ULONG m_i_reserved1;
+ } masix1;
+ } osd1; /* OS dependent 1 */
+ ULONG i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+ ULONG i_version; /* File version (for NFS) */
+ ULONG i_file_acl; /* File ACL */
+ ULONG i_dir_acl; /* Directory ACL */
+ ULONG i_faddr; /* Fragment address */
+ union {
+ struct {
+ UCHAR l_i_frag; /* Fragment number */
+ UCHAR l_i_fsize; /* Fragment size */
+ USHORT i_pad1;
+ ULONG l_i_reserved2[2];
+ } linux2;
+ struct {
+ UCHAR h_i_frag; /* Fragment number */
+ UCHAR h_i_fsize; /* Fragment size */
+ USHORT h_i_mode_high;
+ USHORT h_i_uid_high;
+ USHORT h_i_gid_high;
+ ULONG h_i_author;
+ } hurd2;
+ struct {
+ UCHAR m_i_frag; /* Fragment number */
+ UCHAR m_i_fsize; /* Fragment size */
+ USHORT m_pad1;
+ ULONG m_i_reserved2[2];
+ } masix2;
+ } osd2; /* OS dependent 2 */
+};
+
+#if defined(__KERNEL__) || defined(__linux__)
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_reserved2 osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef __hurd__
+#define i_translator osd1.hurd1.h_i_translator
+#define i_frag osd2.hurd2.h_i_frag;
+#define i_fsize osd2.hurd2.h_i_fsize;
+#define i_uid_high osd2.hurd2.h_i_uid_high
+#define i_gid_high osd2.hurd2.h_i_gid_high
+#define i_author osd2.hurd2.h_i_author
+#endif
+
+#ifdef __masix__
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+#endif
+
+/*
+ * Constants relative to the data blocks
+ */
+#define EXT2_NDIR_BLOCKS 12
+#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
+/*
+ * Inode flags
+ */
+#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
+#define EXT2_UNRM_FL 0x00000002 /* Undelete */
+#define EXT2_COMPR_FL 0x00000004 /* Compress file */
+#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
+#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
+#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
+#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
+#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
+
+
+/*
+ * Structure of a blocks group descriptor
+ */
+struct ext2_group_desc
+{
+ ULONG bg_block_bitmap; /* Blocks bitmap block */
+ ULONG bg_inode_bitmap; /* Inodes bitmap block */
+ ULONG bg_inode_table; /* Inodes table block */
+ USHORT bg_free_blocks_count; /* Free blocks count */
+ USHORT bg_free_inodes_count; /* Free inodes count */
+ USHORT bg_used_dirs_count; /* Directories count */
+ USHORT bg_pad;
+ ULONG bg_reserved[3];
+};
+
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+ ULONG inode; /* Inode number */
+ USHORT rec_len; /* Directory entry length */
+ USHORT name_len; /* Name length */
+ char name[EXT2_NAME_LEN]; /* File name */
+};
+
+typedef struct
+{
+ PDEVICE_OBJECT StorageDevice;
+ struct ext2_super_block* superblock;
+} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+
+
+VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
+ ULONG ino,
+ struct ext2_inode* inode);
+struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
+ ULONG block_group);
+
+typedef struct _EXT2_FCB
+{
+ struct ext2_inode inode;
+} EXT2_FCB, *PEXT2_FCB;
+
+ULONG Ext2BlockMap(PDEVICE_EXTENSION DeviceExt,
+ struct ext2_inode* inode,
+ ULONG offset);
+NTSTATUS Ext2OpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
+ PWSTR FileName);
+NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject,
+ PVOID Buffer,
+ ULONG Length,
+ LARGE_INTEGER Offset);
+NTSTATUS Ext2Create(PDEVICE_OBJECT DeviceObject, PIRP Irp);
+NTSTATUS Ext2DirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: services/fs/ext2/inode.c\r
- * PURPOSE: Manipulating inodes\r
- * PROGRAMMER: David Welch (welch@cwcom.net)\r
- * UPDATE HISTORY:\r
- * 26/12/98: Created\r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/debug.h>\r
-#include <string.h>\r
-\r
-#include "ext2fs.h"\r
-\r
-/* FUNCTIONS ***************************************************************/\r
-\r
-struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,\r
- ULONG block_group)\r
-{\r
- struct ext2_group_desc* buffer;\r
- ULONG block;\r
- struct ext2_group_desc* gdp;\r
- \r
- buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);\r
- \r
- block = block_group / (BLOCKSIZE / sizeof(struct ext2_group_desc));\r
- \r
- Ext2ReadSectors(DeviceExt->StorageDevice,\r
- 2 + block,\r
- 1,\r
- buffer);\r
- \r
- gdp = &buffer[block_group % (BLOCKSIZE / sizeof(struct ext2_group_desc))];\r
- \r
- DPRINT("gdp->bg_free_blocks_count %d\n",gdp->bg_free_blocks_count);\r
- DPRINT("gdp->bg_inode_table %d\n",gdp->bg_inode_table);\r
- \r
- return(gdp);\r
- \r
-}\r
-\r
-#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))\r
-\r
-VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,\r
- ULONG ino,\r
- struct ext2_inode* inode)\r
-{\r
- ULONG block_group;\r
- struct ext2_group_desc* gdp;\r
- ULONG offset;\r
- struct ext2_inode* buffer;\r
- \r
- DPRINT("Ext2ReadInode(DeviceExt %x, ino %d, inode %x)\n",\r
- DeviceExt,ino,inode);\r
- \r
- block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;\r
- \r
- gdp = Ext2LoadGroupDesc(DeviceExt, block_group);\r
- \r
-\r
- \r
- offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;\r
- \r
- buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);\r
- Ext2ReadSectors(DeviceExt->StorageDevice,\r
- gdp->bg_inode_table + (offset / INODES_PER_BLOCK),\r
- 1,\r
- buffer);\r
- memcpy(inode,&buffer[offset % INODES_PER_BLOCK],sizeof(struct ext2_inode));\r
- \r
- DPRINT("inode->i_uid %d\n",inode->i_uid);\r
- DPRINT("inode->i_links_count %d\n",inode->i_links_count);\r
- DPRINT("inode->i_blocks %d\n",inode->i_blocks);\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/ext2/inode.c
+ * PURPOSE: Manipulating inodes
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 26/12/98: Created
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/debug.h>
+#include <string.h>
+
+#include "ext2fs.h"
+
+/* FUNCTIONS ***************************************************************/
+
+struct ext2_group_desc* Ext2LoadGroupDesc(PDEVICE_EXTENSION DeviceExt,
+ ULONG block_group)
+{
+ struct ext2_group_desc* buffer;
+ ULONG block;
+ struct ext2_group_desc* gdp;
+
+ buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+
+ block = block_group / (BLOCKSIZE / sizeof(struct ext2_group_desc));
+
+ Ext2ReadSectors(DeviceExt->StorageDevice,
+ 2 + block,
+ 1,
+ buffer);
+
+ gdp = &buffer[block_group % (BLOCKSIZE / sizeof(struct ext2_group_desc))];
+
+ DPRINT("gdp->bg_free_blocks_count %d\n",gdp->bg_free_blocks_count);
+ DPRINT("gdp->bg_inode_table %d\n",gdp->bg_inode_table);
+
+ return(gdp);
+
+}
+
+#define INODES_PER_BLOCK (BLOCKSIZE / sizeof(struct ext2_inode))
+
+VOID Ext2ReadInode(PDEVICE_EXTENSION DeviceExt,
+ ULONG ino,
+ struct ext2_inode* inode)
+{
+ ULONG block_group;
+ struct ext2_group_desc* gdp;
+ ULONG offset;
+ struct ext2_inode* buffer;
+
+ DPRINT("Ext2ReadInode(DeviceExt %x, ino %d, inode %x)\n",
+ DeviceExt,ino,inode);
+
+ block_group = (ino - 1) / DeviceExt->superblock->s_inodes_per_group;
+
+ gdp = Ext2LoadGroupDesc(DeviceExt, block_group);
+
+
+
+ offset = (ino - 1) % DeviceExt->superblock->s_inodes_per_group;
+
+ buffer = ExAllocatePool(NonPagedPool, BLOCKSIZE);
+ Ext2ReadSectors(DeviceExt->StorageDevice,
+ gdp->bg_inode_table + (offset / INODES_PER_BLOCK),
+ 1,
+ buffer);
+ memcpy(inode,&buffer[offset % INODES_PER_BLOCK],sizeof(struct ext2_inode));
+
+ DPRINT("inode->i_uid %d\n",inode->i_uid);
+ DPRINT("inode->i_links_count %d\n",inode->i_links_count);
+ DPRINT("inode->i_blocks %d\n",inode->i_blocks);
+}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: services/fs/ext2/super.c\r
- * PURPOSE: ext2 filesystem\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY: \r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/string.h>\r
-#include <wstring.h>\r
-\r
-//#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-#include "ext2fs.h"\r
-\r
-/* GLOBALS *****************************************************************/\r
-\r
-static PDRIVER_OBJECT DriverObject;\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-NTSTATUS Ext2CloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)\r
-/*\r
- * FUNCTION: Closes a file\r
- */\r
-{\r
-}\r
-\r
-NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);\r
- PFILE_OBJECT FileObject = Stack->FileObject;\r
- PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;\r
- NTSTATUS Status;\r
- \r
- Status = Ext2CloseFile(DeviceExtension,FileObject);\r
-\r
- Irp->IoStatus.Status = Status;\r
- Irp->IoStatus.Information = 0;\r
- \r
- IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
- return(Status);\r
-}\r
-\r
-NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);\r
- \r
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;\r
- Irp->IoStatus.Information = 0;\r
- return(STATUS_UNSUCCESSFUL);\r
-}\r
-\r
-NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- ULONG Length;\r
- PVOID Buffer;\r
- ULONG Offset;\r
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);\r
- PFILE_OBJECT FileObject = Stack->FileObject;\r
- PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;\r
- NTSTATUS Status;\r
- \r
- DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);\r
- \r
- Length = Stack->Parameters.Read.Length;\r
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);\r
- Offset = Stack->Parameters.Read.ByteOffset;\r
- \r
- Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);\r
- \r
- Irp->IoStatus.Status = Status;\r
- Irp->IoStatus.Information = Length;\r
- IoCompleteRequest(Irp,IO_NO_INCREMENT);\r
- \r
- return(Status);\r
-}\r
-\r
-\r
-NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)\r
-{\r
- PDEVICE_OBJECT DeviceObject;\r
- PDEVICE_EXTENSION DeviceExt;\r
- PVOID BlockBuffer; \r
- struct ext2_super_block* superblock;\r
- \r
- DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);\r
- \r
- BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);\r
- Ext2ReadSectors(DeviceToMount,\r
- 1,\r
- 1,\r
- BlockBuffer);\r
- superblock = BlockBuffer;\r
- \r
- if (superblock->s_magic != EXT2_SUPER_MAGIC)\r
- {\r
- ExFreePool(BlockBuffer);\r
- return(STATUS_UNRECOGNIZED_VOLUME);\r
- }\r
- DPRINT("Volume recognized\n");\r
- DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);\r
- DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);\r
- \r
- IoCreateDevice(DriverObject,\r
- sizeof(DEVICE_EXTENSION),\r
- NULL,\r
- FILE_DEVICE_FILE_SYSTEM,\r
- 0,\r
- FALSE,\r
- &DeviceObject);\r
- DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;\r
- DeviceExt = (PVOID)DeviceObject->DeviceExtension;\r
- \r
- DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,\r
- DeviceToMount);\r
- DeviceExt->superblock = superblock;\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)\r
-{\r
- PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);\r
- PVPB vpb = Stack->Parameters.Mount.Vpb;\r
- PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;\r
- NTSTATUS Status;\r
- \r
- Status = Ext2Mount(DeviceToMount);\r
- \r
- Irp->IoStatus.Status = Status;\r
- Irp->IoStatus.Information = 0;\r
- \r
- IoCompleteRequest(Irp, IO_NO_INCREMENT);\r
- return(Status);\r
-}\r
-\r
-NTSTATUS DriverEntry(PDRIVER_OBJECT _DriverObject,\r
- PUNICODE_STRING RegistryPath)\r
-/*\r
- * FUNCTION: Called by the system to initalize the driver\r
- * ARGUMENTS:\r
- * DriverObject = object describing this driver\r
- * RegistryPath = path to our configuration entries\r
- * RETURNS: Success or failure\r
- */\r
-{\r
- PDEVICE_OBJECT DeviceObject;\r
- NTSTATUS ret;\r
- UNICODE_STRING DeviceNameU;\r
- ANSI_STRING DeviceNameA;\r
- \r
- DbgPrint("Ext2 FSD 0.0.1\n");\r
- \r
- DriverObject = _DriverObject;\r
- \r
- RtlInitAnsiString(&DeviceNameA,"\\Device\\Ext2Fsd");\r
- RtlAnsiStringToUnicodeString(&DeviceNameU,&DeviceNameA,TRUE);\r
- ret = IoCreateDevice(DriverObject,\r
- 0,\r
- &DeviceNameU,\r
- FILE_DEVICE_FILE_SYSTEM,\r
- 0,\r
- FALSE,\r
- &DeviceObject);\r
- if (ret!=STATUS_SUCCESS)\r
- {\r
- return(ret);\r
- }\r
-\r
- DeviceObject->Flags=0;\r
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;\r
- DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;\r
- DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;\r
- DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;\r
- DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =\r
- Ext2FileSystemControl;\r
- DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=\r
- Ext2DirectoryControl;\r
- DriverObject->DriverUnload = NULL;\r
- \r
- DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n",\r
- DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]);\r
- DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL);\r
- \r
- IoRegisterFileSystem(DeviceObject);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: services/fs/ext2/super.c
+ * PURPOSE: ext2 filesystem
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/string.h>
+#include <wstring.h>
+
+//#define NDEBUG
+#include <internal/debug.h>
+
+#include "ext2fs.h"
+
+/* GLOBALS *****************************************************************/
+
+static PDRIVER_OBJECT DriverObject;
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS Ext2CloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
+/*
+ * FUNCTION: Closes a file
+ */
+{
+}
+
+NTSTATUS Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PFILE_OBJECT FileObject = Stack->FileObject;
+ PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+ NTSTATUS Status;
+
+ Status = Ext2CloseFile(DeviceExtension,FileObject);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+}
+
+NTSTATUS Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
+
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ return(STATUS_UNSUCCESSFUL);
+}
+
+NTSTATUS Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ ULONG Length;
+ PVOID Buffer;
+ ULONG Offset;
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PFILE_OBJECT FileObject = Stack->FileObject;
+ PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
+ NTSTATUS Status;
+
+ DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
+
+ Length = Stack->Parameters.Read.Length;
+ Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ Offset = Stack->Parameters.Read.ByteOffset;
+
+ Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = Length;
+ IoCompleteRequest(Irp,IO_NO_INCREMENT);
+
+ return(Status);
+}
+
+
+NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
+{
+ PDEVICE_OBJECT DeviceObject;
+ PDEVICE_EXTENSION DeviceExt;
+ PVOID BlockBuffer;
+ struct ext2_super_block* superblock;
+
+ DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);
+
+ BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
+ Ext2ReadSectors(DeviceToMount,
+ 1,
+ 1,
+ BlockBuffer);
+ superblock = BlockBuffer;
+
+ if (superblock->s_magic != EXT2_SUPER_MAGIC)
+ {
+ ExFreePool(BlockBuffer);
+ return(STATUS_UNRECOGNIZED_VOLUME);
+ }
+ DPRINT("Volume recognized\n");
+ DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);
+ DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);
+
+ IoCreateDevice(DriverObject,
+ sizeof(DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_FILE_SYSTEM,
+ 0,
+ FALSE,
+ &DeviceObject);
+ DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
+ DeviceExt = (PVOID)DeviceObject->DeviceExtension;
+
+ DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
+ DeviceToMount);
+ DeviceExt->superblock = superblock;
+
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+ PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
+ PVPB vpb = Stack->Parameters.Mount.Vpb;
+ PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
+ NTSTATUS Status;
+
+ Status = Ext2Mount(DeviceToMount);
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return(Status);
+}
+
+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;
+ NTSTATUS ret;
+ UNICODE_STRING DeviceNameU;
+ ANSI_STRING DeviceNameA;
+
+ DbgPrint("Ext2 FSD 0.0.1\n");
+
+ DriverObject = _DriverObject;
+
+ RtlInitAnsiString(&DeviceNameA,"\\Device\\Ext2Fsd");
+ RtlAnsiStringToUnicodeString(&DeviceNameU,&DeviceNameA,TRUE);
+ ret = IoCreateDevice(DriverObject,
+ 0,
+ &DeviceNameU,
+ FILE_DEVICE_FILE_SYSTEM,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (ret!=STATUS_SUCCESS)
+ {
+ return(ret);
+ }
+
+ DeviceObject->Flags=0;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;
+ DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
+ Ext2FileSystemControl;
+ DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]=
+ Ext2DirectoryControl;
+ DriverObject->DriverUnload = NULL;
+
+ DPRINT("DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] %x\n",
+ DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]);
+ DPRINT("IRP_MJ_DIRECTORY_CONTROL %d\n",IRP_MJ_DIRECTORY_CONTROL);
+
+ IoRegisterFileSystem(DeviceObject);
+
+ return(STATUS_SUCCESS);
+}
+
Stack = IoGetCurrentIrpStackLocation(Irp);
RequestedDisposition = ((Stack->Parameters.Create.Options>>24)&0xff);
RequestedOptions=Stack->Parameters.Create.Options&FILE_VALID_OPTION_FLAGS;
-DbgPrint("CROptions=%x\n",Stack->Parameters.Create.Options);
-DbgPrint("REquestedOptions=%x\n",RequestedOptions);
+ DPRINT("CROptions=%x\n",Stack->Parameters.Create.Options);
+ DPRINT("REquestedOptions=%x\n",RequestedOptions);
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
||RequestedDisposition==FILE_OPEN_IF
||RequestedDisposition==FILE_OVERWRITE_IF)
{
-DbgPrint("try to create file\n");
+ DPRINT("try to create file\n");
Status=addEntry(DeviceExt,FileObject,RequestedOptions);
}
}
/*
* PURPOSE: Called to close an object if OkayToClose returns true
*/
- VOID (*Close)(VOID);
+ VOID (*Close)(PVOID ObjectBody);
/*
* PURPOSE: Called to close an object if OkayToClose returns true
} OBJECT_TYPE, *POBJECT_TYPE;
-typedef struct _OBJECT
+typedef struct _OBJECT_HEADER
/*
* PURPOSE: Header for every object managed by the object manager
*/
{
UNICODE_STRING Name;
LIST_ENTRY Entry;
- ULONG RefCount;
- ULONG HandleCount;
+ LONG RefCount;
+ LONG HandleCount;
BOOLEAN Permanent;
struct _DIRECTORY_OBJECT* Parent;
POBJECT_TYPE ObjectType;
-#ifndef __INCLUDE_DDK_PSTYPES_H\r
-#define __INCLUDE_DDK_PSTYPES_H\r
-\r
-#undef WIN32_LEAN_AND_MEAN\r
-#include <windows.h> // might be redundant\r
-#include <kernel32/heap.h>\r
-#include <kernel32/atom.h>\r
-#include <internal/hal.h>\r
-\r
-#ifndef TLS_MINIMUM_AVAILABLE\r
- #define TLS_MINIMUM_AVAILABLE (64)\r
-#endif\r
-#ifndef MAX_PATH\r
- #define MAX_PATH (260)\r
-#endif\r
-\r
-typedef NTSTATUS (*PKSTART_ROUTINE)(PVOID StartContext);\r
-\r
-typedef struct _STACK_INFORMATION \r
-{\r
- PVOID BaseAddress;\r
- PVOID UpperAddress;\r
-} STACK_INFORMATION, *PSTACK_INFORMATION;\r
-\r
-typedef struct linux_sigcontext {\r
- int sc_gs;\r
- int sc_fs;\r
- int sc_es;\r
- int sc_ds;\r
- int sc_edi;\r
- int sc_esi;\r
- int sc_ebp;\r
- int sc_esp;\r
- int sc_ebx;\r
- int sc_edx;\r
- int sc_ecx;\r
- int sc_eax;\r
- int sc_trapno;\r
- int sc_err;\r
- int sc_eip;\r
- int sc_cs;\r
- int sc_eflags;\r
- int sc_esp_at_signal;\r
- int sc_ss;\r
- int sc_387;\r
- int sc_mask;\r
- int sc_cr2;\r
-} TRAP_FRAME, *PTRAP_FRAME;\r
-\r
-typedef ULONG THREADINFOCLASS;\r
-\r
-typedef struct _STARTUPINFOW { \r
- DWORD cb; \r
- WCHAR WindowTitle[MAX_PATH];\r
- WCHAR ImageFile[MAX_PATH]; \r
- WCHAR CommandLine[MAX_PATH];\r
- WCHAR DllPath[MAX_PATH];\r
- LPWSTR Reserved[MAX_PATH]; \r
- LPWSTR Desktop[MAX_PATH]; \r
- LPWSTR Title[MAX_PATH]; \r
- DWORD dwX; \r
- DWORD dwY; \r
- DWORD dwXSize; \r
- DWORD dwYSize; \r
- DWORD dwXCountChars; \r
- DWORD dwYCountChars; \r
- DWORD dwFillAttribute; \r
- DWORD dwFlags; \r
- WORD wShowWindow; \r
- WORD cbReserved2; \r
- unsigned char * lpReserved2; \r
- HANDLE hStdInput; \r
- HANDLE hStdOutput; \r
- HANDLE hStdError; \r
-} PROCESSINFOW, *PPROCESSINFOW; \r
-\r
-\r
-\r
-typedef struct _LDR {\r
- UCHAR Initialized;\r
- UCHAR InInitializationOrderModuleList;\r
- PVOID InLoadOrderModuleList;\r
- PVOID InMemoryOrderModuleList;\r
-} LDR, *PLDR;\r
-\r
-\r
-typedef struct _NT_PEB\r
-{\r
- UCHAR InheritedAddressSpace;\r
- UCHAR ReadImageFileExecOptions;\r
- UCHAR BeingDebugged;\r
- LONG ImageBaseAddress; \r
- LDR Ldr;\r
-\r
- WORD NumberOfProcessors;\r
- WORD NtGlobalFlag;\r
-\r
- PPROCESSINFOW StartupInfo;\r
- PHEAP ProcessHeap; \r
- ATOMTABLE LocalAtomTable;\r
- LPCRITICAL_SECTION CriticalSection;\r
- DWORD CriticalSectionTimeout; \r
- WORD MajorVersion; \r
- WORD MinorVersion; \r
- WORD BuildNumber; \r
- WORD PlatformId; \r
-} NT_PEB, *PNT_PEB; \r
-\r
-typedef struct _CLIENT_ID \r
-{\r
- HANDLE UniqueProcess;\r
- HANDLE UniqueThread;\r
-} CLIENT_ID, *PCLIENT_ID;\r
-\r
-typedef struct _NT_TIB {\r
- struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;\r
- PVOID StackBase;\r
- PVOID StackLimit;\r
- PVOID SubSystemTib;\r
- union {\r
- PVOID FiberData;\r
- ULONG Version;\r
- } Fib;\r
- PVOID ArbitraryUserPointer;\r
- struct _NT_TIB *Self;\r
-} NT_TIB, *PNT_TIB;\r
-\r
-typedef struct _NT_TEB\r
-{\r
-\r
- NT_TIB Tib; \r
- CLIENT_ID Cid;\r
- HANDLE RPCHandle;\r
- PVOID TlsData[TLS_MINIMUM_AVAILABLE];\r
- DWORD dwTlsIndex;\r
- NT_PEB *Peb; \r
- DWORD LastErrorCode;\r
- NTSTATUS LastStatusValue; \r
- DWORD LockCount;\r
- UCHAR HardErrorMode;\r
- \r
-} NT_TEB;\r
-\r
-typedef struct _KTHREAD \r
-{\r
- DISPATCHER_HEADER DispatcherHeader;\r
- TIME ElapsedTime;\r
- TIME KernelTime;\r
- TIME UserTime;\r
- STACK_INFORMATION StackInformation;\r
- PVOID ServiceDescriptorTable; // points to KeServiceDescriptorTable\r
- KAFFINITY Affinity;\r
- KPRIORITY CurrentPriority;\r
- KPRIORITY BasePriority;\r
- ULONG Quantum;\r
- UCHAR ThreadState; //Thread state is a typeless enum, otherwise it should be const integer\r
- ULONG FreezeCount;\r
- LONG SuspendCount;\r
- PTRAP_FRAME TrapFrame; \r
- PVOID *Tls;\r
- KWAIT_BLOCK WaitBlock[4]; \r
- struct _KMUTANT* MutantList;\r
- PLIST_ENTRY ApcList;\r
- UCHAR KernelApcDisable;\r
- KTIMER TimerBlock;\r
- KDEVICE_QUEUE DeviceQueue;\r
- NT_TEB* Teb;\r
- \r
- /*\r
- * PURPOSE: CPU state\r
- * NOTE: I have temporarily added this to give somewhere to store\r
- * cpu state when the thread isn't running\r
- */\r
- hal_thread_state Context;\r
- LIST_ENTRY Entry;\r
- ULONG LastTick;\r
-} KTHREAD, *PKTHREAD;\r
-\r
-\r
-// According to documentation the stack should have a commited [ 1 page ] and\r
-// a reserved part [ 1 M ] but can be specified otherwise in the image file.\r
-\r
-typedef struct _INITIAL_TEB {\r
- PVOID StackBase;\r
- PVOID StackLimit;\r
- PVOID StackCommit;\r
- PVOID StackCommitMax;\r
- PVOID StackReserved;\r
-} INITIAL_TEB, *PINITIAL_TEB;\r
-\r
-\r
-\r
-\r
-\r
-\r
-// TopLevelIrp can be one of the following values:\r
-// FIXME I belong somewhere else\r
-\r
-#define FSRTL_FSP_TOP_LEVEL_IRP (0x01)\r
-#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)\r
-#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)\r
-#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)\r
-#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)\r
-\r
-typedef struct _TOP_LEVEL_IRP\r
-{\r
- PIRP TopLevelIrp;\r
- ULONG TopLevelIrpConst;\r
-} TOP_LEVEL_IRP;\r
-\r
-typedef struct _ETHREAD {\r
- KTHREAD Tcb;\r
- TIME CreateTime;\r
- TIME ExitTime;\r
- NTSTATUS ExitStatus;\r
- LIST_ENTRY PostBlockList;\r
- LIST_ENTRY TerminationPortList; \r
- ULONG ActiveTimerListLock;\r
- PVOID ActiveTimerListHead;\r
- CLIENT_ID Cid;\r
- PLARGE_INTEGER LpcReplySemaphore;\r
- PVOID LpcReplyMessage;\r
- PLARGE_INTEGER LpcReplyMessageId;\r
- PVOID ImpersonationInfo;\r
- LIST_ENTRY IrpList; //\r
- TOP_LEVEL_IRP TopLevelIrp;\r
- ULONG ReadClusterSize;\r
- UCHAR ForwardClusterOnly;\r
- UCHAR DisablePageFaultClustering;\r
- UCHAR DeadThread;\r
- UCHAR HasTerminated;\r
- ACCESS_MASK GrantedAccess;\r
- struct _EPROCESS* ThreadsProcess;\r
- PKSTART_ROUTINE StartAddress;\r
- LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func\r
- UCHAR LpcExitThreadCalled;\r
- UCHAR HardErrorsAreDisabled;\r
-} ETHREAD, *PETHREAD;\r
-\r
-\r
-typedef struct _KPROCESS \r
-{\r
- DISPATCHER_HEADER DispatcherHeader;\r
- PVOID PageTableDirectory; // FIXME: I shoud point to a PTD\r
- TIME ElapsedTime;\r
- TIME KernelTime;\r
- TIME UserTime;\r
- LIST_ENTRY InMemoryList; \r
- LIST_ENTRY SwappedOutList; \r
- KSPIN_LOCK SpinLock;\r
- KAFFINITY Affinity;\r
- ULONG StackCount;\r
- KPRIORITY BasePriority;\r
- ULONG DefaultThreadQuantum;\r
- UCHAR ProcessState;\r
- ULONG ThreadSeed;\r
- UCHAR DisableBoost;\r
- \r
- /*\r
- * Added by David Welch (welch@mcmail.com)\r
- */\r
- LIST_ENTRY MemoryAreaList;\r
- HANDLE_TABLE HandleTable;\r
-} KPROCESS, *PKPROCESS;\r
-\r
-typedef struct _EPROCESS\r
-{\r
- KPROCESS Pcb;\r
-} EPROCESS, *PEPROCESS;\r
-\r
-#define PROCESS_STATE_TERMINATED (1)\r
-#define PROCESS_STATE_ACTIVE (2)\r
-\r
-#endif /* __INCLUDE_DDK_PSTYPES_H */\r
+#ifndef __INCLUDE_DDK_PSTYPES_H
+#define __INCLUDE_DDK_PSTYPES_H
+
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h> // might be redundant
+#include <kernel32/heap.h>
+#include <kernel32/atom.h>
+#include <internal/hal.h>
+
+#ifndef TLS_MINIMUM_AVAILABLE
+ #define TLS_MINIMUM_AVAILABLE (64)
+#endif
+#ifndef MAX_PATH
+ #define MAX_PATH (260)
+#endif
+
+typedef NTSTATUS (*PKSTART_ROUTINE)(PVOID StartContext);
+
+typedef struct _STACK_INFORMATION
+{
+ PVOID BaseAddress;
+ PVOID UpperAddress;
+} STACK_INFORMATION, *PSTACK_INFORMATION;
+
+typedef struct linux_sigcontext {
+ int sc_gs;
+ int sc_fs;
+ int sc_es;
+ int sc_ds;
+ int sc_edi;
+ int sc_esi;
+ int sc_ebp;
+ int sc_esp;
+ int sc_ebx;
+ int sc_edx;
+ int sc_ecx;
+ int sc_eax;
+ int sc_trapno;
+ int sc_err;
+ int sc_eip;
+ int sc_cs;
+ int sc_eflags;
+ int sc_esp_at_signal;
+ int sc_ss;
+ int sc_387;
+ int sc_mask;
+ int sc_cr2;
+} TRAP_FRAME, *PTRAP_FRAME;
+
+typedef ULONG THREADINFOCLASS;
+
+typedef struct _STARTUPINFOW {
+ DWORD cb;
+ WCHAR WindowTitle[MAX_PATH];
+ WCHAR ImageFile[MAX_PATH];
+ WCHAR CommandLine[MAX_PATH];
+ WCHAR DllPath[MAX_PATH];
+ LPWSTR Reserved[MAX_PATH];
+ LPWSTR Desktop[MAX_PATH];
+ LPWSTR Title[MAX_PATH];
+ DWORD dwX;
+ DWORD dwY;
+ DWORD dwXSize;
+ DWORD dwYSize;
+ DWORD dwXCountChars;
+ DWORD dwYCountChars;
+ DWORD dwFillAttribute;
+ DWORD dwFlags;
+ WORD wShowWindow;
+ WORD cbReserved2;
+ unsigned char * lpReserved2;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+} PROCESSINFOW, *PPROCESSINFOW;
+
+
+
+typedef struct _LDR {
+ UCHAR Initialized;
+ UCHAR InInitializationOrderModuleList;
+ PVOID InLoadOrderModuleList;
+ PVOID InMemoryOrderModuleList;
+} LDR, *PLDR;
+
+
+typedef struct _NT_PEB
+{
+ UCHAR InheritedAddressSpace;
+ UCHAR ReadImageFileExecOptions;
+ UCHAR BeingDebugged;
+ LONG ImageBaseAddress;
+ LDR Ldr;
+
+ WORD NumberOfProcessors;
+ WORD NtGlobalFlag;
+
+ PPROCESSINFOW StartupInfo;
+ PHEAP ProcessHeap;
+ ATOMTABLE LocalAtomTable;
+ LPCRITICAL_SECTION CriticalSection;
+ DWORD CriticalSectionTimeout;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD BuildNumber;
+ WORD PlatformId;
+} NT_PEB, *PNT_PEB;
+
+typedef struct _CLIENT_ID
+{
+ HANDLE UniqueProcess;
+ HANDLE UniqueThread;
+} CLIENT_ID, *PCLIENT_ID;
+
+typedef struct _NT_TIB {
+ struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID SubSystemTib;
+ union {
+ PVOID FiberData;
+ ULONG Version;
+ } Fib;
+ PVOID ArbitraryUserPointer;
+ struct _NT_TIB *Self;
+} NT_TIB, *PNT_TIB;
+
+typedef struct _NT_TEB
+{
+
+ NT_TIB Tib;
+ CLIENT_ID Cid;
+ HANDLE RPCHandle;
+ PVOID TlsData[TLS_MINIMUM_AVAILABLE];
+ DWORD dwTlsIndex;
+ NT_PEB *Peb;
+ DWORD LastErrorCode;
+ NTSTATUS LastStatusValue;
+ DWORD LockCount;
+ UCHAR HardErrorMode;
+
+} NT_TEB;
+
+typedef struct _KTHREAD
+{
+ DISPATCHER_HEADER DispatcherHeader;
+ TIME ElapsedTime;
+ TIME KernelTime;
+ TIME UserTime;
+ STACK_INFORMATION StackInformation;
+ PVOID ServiceDescriptorTable; // points to KeServiceDescriptorTable
+ KAFFINITY Affinity;
+ KPRIORITY CurrentPriority;
+ KPRIORITY BasePriority;
+ ULONG Quantum;
+ UCHAR ThreadState; //Thread state is a typeless enum, otherwise it should be const integer
+ ULONG FreezeCount;
+ LONG SuspendCount;
+ PTRAP_FRAME TrapFrame;
+ PVOID *Tls;
+ KWAIT_BLOCK WaitBlock[4];
+ struct _KMUTANT* MutantList;
+ PLIST_ENTRY ApcList;
+ UCHAR KernelApcDisable;
+ KTIMER TimerBlock;
+ KDEVICE_QUEUE DeviceQueue;
+ NT_TEB* Teb;
+
+ /*
+ * PURPOSE: CPU state
+ * NOTE: I have temporarily added this to give somewhere to store
+ * cpu state when the thread isn't running
+ */
+ hal_thread_state Context;
+ LIST_ENTRY Entry;
+ ULONG LastTick;
+} KTHREAD, *PKTHREAD;
+
+
+// According to documentation the stack should have a commited [ 1 page ] and
+// a reserved part [ 1 M ] but can be specified otherwise in the image file.
+
+typedef struct _INITIAL_TEB {
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID StackCommit;
+ PVOID StackCommitMax;
+ PVOID StackReserved;
+} INITIAL_TEB, *PINITIAL_TEB;
+
+
+
+
+
+
+// TopLevelIrp can be one of the following values:
+// FIXME I belong somewhere else
+
+#define FSRTL_FSP_TOP_LEVEL_IRP (0x01)
+#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02)
+#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03)
+#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04)
+#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04)
+
+typedef struct _TOP_LEVEL_IRP
+{
+ PIRP TopLevelIrp;
+ ULONG TopLevelIrpConst;
+} TOP_LEVEL_IRP;
+
+typedef struct _ETHREAD {
+ KTHREAD Tcb;
+ TIME CreateTime;
+ TIME ExitTime;
+ NTSTATUS ExitStatus;
+ LIST_ENTRY PostBlockList;
+ LIST_ENTRY TerminationPortList;
+ ULONG ActiveTimerListLock;
+ PVOID ActiveTimerListHead;
+ CLIENT_ID Cid;
+ PLARGE_INTEGER LpcReplySemaphore;
+ PVOID LpcReplyMessage;
+ PLARGE_INTEGER LpcReplyMessageId;
+ PVOID ImpersonationInfo;
+ LIST_ENTRY IrpList; //
+ TOP_LEVEL_IRP TopLevelIrp;
+ ULONG ReadClusterSize;
+ UCHAR ForwardClusterOnly;
+ UCHAR DisablePageFaultClustering;
+ UCHAR DeadThread;
+ UCHAR HasTerminated;
+ ACCESS_MASK GrantedAccess;
+ struct _EPROCESS* ThreadsProcess;
+ PKSTART_ROUTINE StartAddress;
+ LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func
+ UCHAR LpcExitThreadCalled;
+ UCHAR HardErrorsAreDisabled;
+} ETHREAD, *PETHREAD;
+
+
+typedef struct _KPROCESS
+{
+ DISPATCHER_HEADER DispatcherHeader;
+ PVOID PageTableDirectory; // FIXME: I shoud point to a PTD
+ TIME ElapsedTime;
+ TIME KernelTime;
+ TIME UserTime;
+ LIST_ENTRY InMemoryList;
+ LIST_ENTRY SwappedOutList;
+ KSPIN_LOCK SpinLock;
+ KAFFINITY Affinity;
+ ULONG StackCount;
+ KPRIORITY BasePriority;
+ ULONG DefaultThreadQuantum;
+ UCHAR ProcessState;
+ ULONG ThreadSeed;
+ UCHAR DisableBoost;
+
+ /*
+ * Added by David Welch (welch@mcmail.com)
+ */
+ LIST_ENTRY MemoryAreaList;
+ HANDLE_TABLE HandleTable;
+} KPROCESS, *PKPROCESS;
+
+typedef struct _EPROCESS
+{
+ KPROCESS Pcb;
+} EPROCESS, *PEPROCESS;
+
+#define PROCESS_STATE_TERMINATED (1)
+#define PROCESS_STATE_ACTIVE (2)
+
+#endif /* __INCLUDE_DDK_PSTYPES_H */
unsigned short reserved11;
unsigned short trap;
unsigned short iomap_base;
-
+
unsigned short nr;
+ PVOID KernelStackBase;
+ PVOID SavedKernelEsp;
+ PVOID SavedKernelStackBase;
unsigned char io_bitmap[1];
} hal_thread_state;
-#ifndef __INCLUDE_INTERNAL_PSMGR_H\r
-#define __INCLUDE_INTERNAL_PSMGR_H\r
-\r
-#include <internal/hal.h>\r
-\r
-extern PEPROCESS SystemProcess;\r
-extern HANDLE SystemProcessHandle;\r
-\r
-extern POBJECT_TYPE PsThreadType;\r
-extern POBJECT_TYPE PsProcessType;\r
-\r
-void PsInitThreadManagment(void);\r
-VOID PsInitProcessManagment(VOID);\r
-VOID PsInitIdleThread(VOID);\r
-VOID PsDispatchThread(VOID);\r
-VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);\r
-\r
-/*\r
- * PURPOSE: Thread states\r
- */\r
-enum\r
-{\r
- /*\r
- * PURPOSE: Don't touch \r
- */\r
- THREAD_STATE_INVALID,\r
- \r
- /*\r
- * PURPOSE: Waiting to be dispatched\r
- */\r
- THREAD_STATE_RUNNABLE,\r
- \r
- /*\r
- * PURPOSE: Currently running\r
- */\r
- THREAD_STATE_RUNNING,\r
- \r
- /*\r
- * PURPOSE: Doesn't want to run\r
- */\r
- THREAD_STATE_SUSPENDED,\r
- \r
- /*\r
- * Waiting to be freed\r
- */\r
- THREAD_STATE_TERMINATED,\r
-};\r
-\r
-/*\r
- * Functions the HAL must provide\r
- */\r
-\r
-void HalInitFirstTask(PETHREAD thread);\r
-BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);\r
-void HalTaskSwitch(PKTHREAD thread);\r
-NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);\r
-\r
-#endif\r
+#ifndef __INCLUDE_INTERNAL_PSMGR_H
+#define __INCLUDE_INTERNAL_PSMGR_H
+
+#include <internal/hal.h>
+
+extern PEPROCESS SystemProcess;
+extern HANDLE SystemProcessHandle;
+
+extern POBJECT_TYPE PsThreadType;
+extern POBJECT_TYPE PsProcessType;
+
+void PsInitThreadManagment(void);
+VOID PsInitProcessManagment(VOID);
+VOID PsInitIdleThread(VOID);
+VOID PsDispatchThread(VOID);
+VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus);
+
+/*
+ * PURPOSE: Thread states
+ */
+enum
+{
+ /*
+ * PURPOSE: Don't touch
+ */
+ THREAD_STATE_INVALID,
+
+ /*
+ * PURPOSE: Waiting to be dispatched
+ */
+ THREAD_STATE_RUNNABLE,
+
+ /*
+ * PURPOSE: Currently running
+ */
+ THREAD_STATE_RUNNING,
+
+ /*
+ * PURPOSE: Doesn't want to run
+ */
+ THREAD_STATE_SUSPENDED,
+
+ /*
+ * Waiting to be freed
+ */
+ THREAD_STATE_TERMINATED,
+};
+
+/*
+ * Functions the HAL must provide
+ */
+
+void HalInitFirstTask(PETHREAD thread);
+BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext);
+void HalTaskSwitch(PKTHREAD thread);
+NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
+
+#endif
#endif
-typedef unsigned int size_t;
+typedef int size_t;
typedef size_t __kernel_size_t;
#endif /* _LINUX_TYPES_H */
-;\r
-; crtdll.def\r
-;\r
-; Exports from crtdll.dll from Windows 95 SYSTEM directory. Hopefully this\r
-; should also work with the crtdll provided with Windows NT.\r
-;\r
-; Contributors:\r
-; Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>\r
-;\r
-; THIS SOFTWARE IS NOT COPYRIGHTED\r
-;\r
-; This source code is offered for use in the public domain. You may\r
-; use, modify or distribute it freely.\r
-;\r
-; This code is distributed in the hope that it will be useful but\r
-; WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY\r
-; DISCLAMED. This includes but is not limited to warrenties of\r
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
-;\r
-; $Revision: 1.1 $\r
-; $Author: dwelch $\r
-; $Date: 1999/01/04 23:01:18 $\r
-;\r
-; These three functions appear to be name mangled in some way, so GCC is\r
-; probably not going to be able to use them in any case.\r
-;\r
-; ??2@YAPAXI@Z\r
-; ??3@YAXPAX@Z\r
-; ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z\r
-;\r
-; These are functions for which I have not yet written prototypes or\r
-; otherwise set up (they are still included below though unlike those\r
-; first three).\r
-;\r
-; _CIacos\r
-; _CIasin\r
-; _CIatan\r
-; _CIatan2\r
-; _CIcos\r
-; _CIcosh\r
-; _CIexp\r
-; _CIfmod\r
-; _CIlog\r
-; _CIlog10\r
-; _CIpow\r
-; _CIsin\r
-; _CIsinh\r
-; _CIsqrt\r
-; _CItan\r
-; _CItanh\r
-; __dllonexit\r
-; __mb_cur_max_dll\r
-; __threadhandle\r
-; __threadid\r
-; _abnormal_termination\r
-; _acmdln_dll\r
-; _aexit_rtn_dll\r
-; _amsg_exit\r
-; _commit\r
-; _commode_dll\r
-; _cpumode_dll\r
-; _ctype\r
-; _daylight_dll\r
-; _environ_dll\r
-; _expand\r
-; _fcloseall\r
-; _filbuf\r
-; _fileinfo_dll\r
-; _flsbuf\r
-; _flushall\r
-; _fmode_dll\r
-; _fpieee_flt\r
-; _fsopen\r
-; _ftol\r
-; _getdiskfree\r
-; _getdllprocaddr\r
-; _getdrive\r
-; _getdrives\r
-; _getsystime\r
-; _getw\r
-; _initterm\r
-; _ismbbalnum\r
-; _ismbbalpha\r
-; _ismbbgraph\r
-; _ismbbkalnum\r
-; _ismbbkana\r
-; _ismbbkpunct\r
-; _ismbblead\r
-; _ismbbprint\r
-; _ismbbpunct\r
-; _ismbbtrail\r
-; _ismbcalpha\r
-; _ismbcdigit\r
-; _ismbchira\r
-; _ismbckata\r
-; _ismbcl0\r
-; _ismbcl1\r
-; _ismbcl2\r
-; _ismbclegal\r
-; _ismbclower\r
-; _ismbcprint\r
-; _ismbcspace\r
-; _ismbcsymbol\r
-; _ismbcupper\r
-; _ismbslead\r
-; _ismbstrail\r
-; _lfind\r
-; _loaddll\r
-; _lrotl\r
-; _lrotr\r
-; _lsearch\r
-; _makepath\r
-; _matherr\r
-; _mbbtombc\r
-; _mbbtype\r
-; _mbccpy\r
-; _mbcjistojms\r
-; _mbcjmstojis\r
-; _mbclen\r
-; _mbctohira\r
-; _mbctokata\r
-; _mbctolower\r
-; _mbctombb\r
-; _mbctoupper\r
-; _mbctype\r
-; _mbsbtype\r
-; _mbscat\r
-; _mbscmp\r
-; _mbscpy\r
-; _mbscspn\r
-; _mbsdec\r
-; _mbsdup\r
-; _mbsicmp\r
-; _mbsinc\r
-; _mbslen\r
-; _mbslwr\r
-; _mbsnbcat\r
-; _mbsnbcmp\r
-; _mbsnbcnt\r
-; _mbsnbcpy\r
-; _mbsnbicmp\r
-; _mbsnbset\r
-; _mbsnccnt\r
-; _mbsncmp\r
-; _mbsncpy\r
-; _mbsnextc\r
-; _mbsnicmp\r
-; _mbsninc\r
-; _mbsnset\r
-; _mbspbrk\r
-; _mbsrchr\r
-; _mbsrev\r
-; _mbsset\r
-; _mbsspn\r
-; _mbsspnp\r
-; _mbsstr\r
-; _mbstrlen\r
-; _mbsupr\r
-; _onexit\r
-; _osver_dll\r
-; _osversion_dll\r
-; _pctype_dll\r
-; _purecall\r
-; _putw\r
-; _pwctype_dll\r
-; _rmtmp\r
-; _rotl\r
-; _rotr\r
-; _setsystime\r
-; _snprintf\r
-; _snwprintf\r
-; _splitpath\r
-; _strdate\r
-; _strdec\r
-; _strinc\r
-; _strncnt\r
-; _strnextc\r
-; _strninc\r
-; _strspnp\r
-; _strtime\r
-; _tempnam\r
-; _timezone_dll\r
-; _tzname\r
-; _tzset\r
-; _ultoa\r
-; _unloaddll\r
-; _vsnprintf\r
-; _vsnwprintf\r
-; _winmajor_dll\r
-; _winminor_dll\r
-; _winver_dll\r
-; _wtoi\r
-; _wtol\r
-;\r
-EXPORTS\r
-_CIacos\r
-_CIasin\r
-_CIatan\r
-_CIatan2\r
-_CIcos\r
-_CIcosh\r
-_CIexp\r
-_CIfmod\r
-_CIlog\r
-_CIlog10\r
-_CIpow\r
-_CIsin\r
-_CIsinh\r
-_CIsqrt\r
-_CItan\r
-_CItanh\r
-_HUGE_dll\r
-_XcptFilter\r
-__GetMainArgs\r
-__argc_dll\r
-__argv_dll\r
-__dllonexit\r
-__doserrno\r
-__fpecode\r
-__isascii\r
-__iscsym\r
-__iscsymf\r
-__mb_cur_max_dll\r
-__pxcptinfoptrs\r
-__threadhandle\r
-__threadid\r
-__toascii\r
-_abnormal_termination\r
-_access\r
-_acmdln_dll\r
-_aexit_rtn_dll\r
-_amsg_exit\r
-_assert\r
-_basemajor_dll\r
-_baseminor_dll\r
-_baseversion_dll\r
-_beep\r
-_beginthread\r
-_c_exit\r
-_cabs\r
-_cexit\r
-_cgets\r
-_chdir\r
-_chdrive\r
-_chgsign\r
-_chmod\r
-_chsize\r
-_clearfp\r
-_close\r
-_commit\r
-_commode_dll\r
-_control87\r
-_controlfp\r
-_copysign\r
-_cprintf\r
-_cpumode_dll\r
-_cputs\r
-_creat\r
-_cscanf\r
-_ctype\r
-_cwait\r
-_daylight_dll\r
-_dup\r
-_dup2\r
-_ecvt\r
-_endthread\r
-_environ_dll\r
-_eof\r
-_errno\r
-_except_handler2\r
-_execl\r
-_execle\r
-_execlp\r
-_execlpe\r
-_execv\r
-_execve\r
-_execvp\r
-_execvpe\r
-_exit\r
-_expand\r
-_fcloseall\r
-_fcvt\r
-_fdopen\r
-_fgetchar\r
-_fgetwchar\r
-_filbuf\r
-_fileinfo_dll\r
-_filelength\r
-_fileno\r
-_findclose\r
-_findfirst\r
-_findnext\r
-_finite\r
-_flsbuf\r
-_flushall\r
-_fmode_dll\r
-_fpclass\r
-_fpieee_flt\r
-_fpreset\r
-_fputchar\r
-_fputwchar\r
-_fsopen\r
-_fstat\r
-_ftime\r
-_ftol\r
-_fullpath\r
-_futime\r
-_gcvt\r
-_get_osfhandle\r
-_getch\r
-_getche\r
-_getcwd\r
-_getdcwd\r
-_getdiskfree\r
-_getdllprocaddr\r
-_getdrive\r
-_getdrives\r
-_getpid\r
-_getsystime\r
-_getw\r
-_global_unwind2\r
-_heapchk\r
-_heapmin\r
-_heapset\r
-_heapwalk\r
-_hypot\r
-_initterm\r
-_iob\r
-_isatty\r
-_isctype\r
-_ismbbalnum\r
-_ismbbalpha\r
-_ismbbgraph\r
-_ismbbkalnum\r
-_ismbbkana\r
-_ismbbkpunct\r
-_ismbblead\r
-_ismbbprint\r
-_ismbbpunct\r
-_ismbbtrail\r
-_ismbcalpha\r
-_ismbcdigit\r
-_ismbchira\r
-_ismbckata\r
-_ismbcl0\r
-_ismbcl1\r
-_ismbcl2\r
-_ismbclegal\r
-_ismbclower\r
-_ismbcprint\r
-_ismbcspace\r
-_ismbcsymbol\r
-_ismbcupper\r
-_ismbslead\r
-_ismbstrail\r
-_isnan\r
-_itoa\r
-_j0\r
-_j1\r
-_jn\r
-_kbhit\r
-_lfind\r
-_loaddll\r
-_local_unwind2\r
-_locking\r
-_logb\r
-_lrotl\r
-_lrotr\r
-_lsearch\r
-_lseek\r
-_ltoa\r
-_makepath\r
-_matherr\r
-_mbbtombc\r
-_mbbtype\r
-_mbccpy\r
-_mbcjistojms\r
-_mbcjmstojis\r
-_mbclen\r
-_mbctohira\r
-_mbctokata\r
-_mbctolower\r
-_mbctombb\r
-_mbctoupper\r
-_mbctype\r
-_mbsbtype\r
-_mbscat\r
-_mbschr\r
-_mbscmp\r
-_mbscpy\r
-_mbscspn\r
-_mbsdec\r
-_mbsdup\r
-_mbsicmp\r
-_mbsinc\r
-_mbslen\r
-_mbslwr\r
-_mbsnbcat\r
-_mbsnbcmp\r
-_mbsnbcnt\r
-_mbsnbcpy\r
-_mbsnbicmp\r
-_mbsnbset\r
-_mbsncat\r
-_mbsnccnt\r
-_mbsncmp\r
-_mbsncpy\r
-_mbsnextc\r
-_mbsnicmp\r
-_mbsninc\r
-_mbsnset\r
-_mbspbrk\r
-_mbsrchr\r
-_mbsrev\r
-_mbsset\r
-_mbsspn\r
-_mbsspnp\r
-_mbsstr\r
-_mbstok\r
-_mbstrlen\r
-_mbsupr\r
-_memccpy\r
-_memicmp\r
-_mkdir\r
-_mktemp\r
-_msize\r
-_nextafter\r
-_onexit\r
-_open\r
-_open_osfhandle\r
-_osmajor_dll\r
-_osminor_dll\r
-_osmode_dll\r
-_osver_dll\r
-_osversion_dll\r
-_pclose\r
-_pctype_dll\r
-_pgmptr_dll\r
-_pipe\r
-_popen\r
-_purecall\r
-_putch\r
-_putenv\r
-_putw\r
-_pwctype_dll\r
-_read\r
-_rmdir\r
-_rmtmp\r
-_rotl\r
-_rotr\r
-_scalb\r
-_searchenv\r
-_seterrormode\r
-_setjmp\r
-_setmode\r
-_setsystime\r
-_sleep\r
-_snprintf\r
-_snwprintf\r
-_sopen\r
-_spawnl\r
-_spawnle\r
-_spawnlp\r
-_spawnlpe\r
-_spawnv\r
-_spawnve\r
-_spawnvp\r
-_spawnvpe\r
-_splitpath\r
-_stat\r
-_statusfp\r
-_strcmpi\r
-_strdate\r
-_strdec\r
-_strdup\r
-_strerror\r
-_stricmp\r
-_stricoll\r
-_strinc\r
-_strlwr\r
-_strncnt\r
-_strnextc\r
-_strnicmp\r
-_strninc\r
-_strnset\r
-_strrev\r
-_strset\r
-_strspnp\r
-_strtime\r
-_strupr\r
-_swab\r
-_sys_errlist\r
-_sys_nerr_dll\r
-_tell\r
-_tempnam\r
-_timezone_dll\r
-_tolower\r
-_toupper\r
-_tzname\r
-_tzset\r
-_ultoa\r
-_umask\r
-_ungetch\r
-_unlink\r
-_unloaddll\r
-_utime\r
-_vsnprintf\r
-_vsnwprintf\r
-_wcsdup\r
-_wcsicmp\r
-_wcsicoll\r
-_wcslwr\r
-_wcsnicmp\r
-_wcsnset\r
-_wcsrev\r
-_wcsset\r
-_wcsupr\r
-_winmajor_dll\r
-_winminor_dll\r
-_winver_dll\r
-_write\r
-_wtoi\r
-_wtol\r
-_y0\r
-_y1\r
-_yn\r
-abort\r
-abs\r
-acos\r
-asctime\r
-asin\r
-atan\r
-atan2\r
-atexit\r
-atof\r
-atoi\r
-atol\r
-bsearch\r
-calloc\r
-ceil\r
-clearerr\r
-clock\r
-cos\r
-cosh\r
-ctime\r
-difftime\r
-div\r
-exit\r
-exp\r
-fabs\r
-fclose\r
-feof\r
-ferror\r
-fflush\r
-fgetc\r
-fgetpos\r
-fgets\r
-fgetwc\r
-floor\r
-fmod\r
-fopen\r
-fprintf\r
-fputc\r
-fputs\r
-fputwc\r
-fread\r
-free\r
-freopen\r
-frexp\r
-fscanf\r
-fseek\r
-fsetpos\r
-ftell\r
-fwprintf\r
-fwrite\r
-fwscanf\r
-getc\r
-getchar\r
-getenv\r
-gets\r
-gmtime\r
-is_wctype\r
-isalnum\r
-isalpha\r
-iscntrl\r
-isdigit\r
-isgraph\r
-isleadbyte\r
-islower\r
-isprint\r
-ispunct\r
-isspace\r
-isupper\r
-iswalnum\r
-iswalpha\r
-iswascii\r
-iswcntrl\r
-iswctype\r
-iswdigit\r
-iswgraph\r
-iswlower\r
-iswprint\r
-iswpunct\r
-iswspace\r
-iswupper\r
-iswxdigit\r
-isxdigit\r
-labs\r
-ldexp\r
-ldiv\r
-localeconv\r
-localtime\r
-log\r
-log10\r
-longjmp\r
-malloc\r
-mblen\r
-mbstowcs\r
-mbtowc\r
-memchr\r
-memcmp\r
-memcpy\r
-memmove\r
-memset\r
-mktime\r
-modf\r
-perror\r
-pow\r
-printf\r
-putc\r
-putchar\r
-puts\r
-qsort\r
-raise\r
-rand\r
-realloc\r
-remove\r
-rename\r
-rewind\r
-scanf\r
-setbuf\r
-setlocale\r
-setvbuf\r
-signal\r
-sin\r
-sinh\r
-sprintf\r
-sqrt\r
-srand\r
-sscanf\r
-strcat\r
-strchr\r
-strcmp\r
-strcoll\r
-strcpy\r
-strcspn\r
-strerror\r
-strftime\r
-strlen\r
-strncat\r
-strncmp\r
-strncpy\r
-strpbrk\r
-strrchr\r
-strspn\r
-strstr\r
-strtod\r
-strtok\r
-strtol\r
-strtoul\r
-strxfrm\r
-swprintf\r
-swscanf\r
-system\r
-tan\r
-tanh\r
-time\r
-tmpfile\r
-tmpnam\r
-tolower\r
-toupper\r
-towlower\r
-towupper\r
-ungetc\r
-ungetwc\r
-vfprintf\r
-vfwprintf\r
-vprintf\r
-vsprintf\r
-vswprintf\r
-vwprintf\r
-wcscat\r
-wcschr\r
-wcscmp\r
-wcscoll\r
-wcscpy\r
-wcscspn\r
-wcsftime\r
-wcslen\r
-wcsncat\r
-wcsncmp\r
-wcsncpy\r
-wcspbrk\r
-wcsrchr\r
-wcsspn\r
-wcsstr\r
-wcstod\r
-wcstok\r
-wcstol\r
-wcstombs\r
-wcstoul\r
-wcsxfrm\r
-wctomb\r
-wprintf\r
-wscanf\r
+;
+; crtdll.def
+;
+; Exports from crtdll.dll from Windows 95 SYSTEM directory. Hopefully this
+; should also work with the crtdll provided with Windows NT.
+;
+; Contributors:
+; Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+;
+; THIS SOFTWARE IS NOT COPYRIGHTED
+;
+; This source code is offered for use in the public domain. You may
+; use, modify or distribute it freely.
+;
+; This code is distributed in the hope that it will be useful but
+; WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+; DISCLAMED. This includes but is not limited to warrenties of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+;
+; $Revision: 1.2 $
+; $Author: dwelch $
+; $Date: 1999/01/16 21:02:58 $
+;
+; These three functions appear to be name mangled in some way, so GCC is
+; probably not going to be able to use them in any case.
+;
+; ??2@YAPAXI@Z
+; ??3@YAXPAX@Z
+; ?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z
+;
+; These are functions for which I have not yet written prototypes or
+; otherwise set up (they are still included below though unlike those
+; first three).
+;
+; _CIacos
+; _CIasin
+; _CIatan
+; _CIatan2
+; _CIcos
+; _CIcosh
+; _CIexp
+; _CIfmod
+; _CIlog
+; _CIlog10
+; _CIpow
+; _CIsin
+; _CIsinh
+; _CIsqrt
+; _CItan
+; _CItanh
+; __dllonexit
+; __mb_cur_max_dll
+; __threadhandle
+; __threadid
+; _abnormal_termination
+; _acmdln_dll
+; _aexit_rtn_dll
+; _amsg_exit
+; _commit
+; _commode_dll
+; _cpumode_dll
+; _ctype
+; _daylight_dll
+; _environ_dll
+; _expand
+; _fcloseall
+; _filbuf
+; _fileinfo_dll
+; _flsbuf
+; _flushall
+; _fmode_dll
+; _fpieee_flt
+; _fsopen
+; _ftol
+; _getdiskfree
+; _getdllprocaddr
+; _getdrive
+; _getdrives
+; _getsystime
+; _getw
+; _initterm
+; _ismbbalnum
+; _ismbbalpha
+; _ismbbgraph
+; _ismbbkalnum
+; _ismbbkana
+; _ismbbkpunct
+; _ismbblead
+; _ismbbprint
+; _ismbbpunct
+; _ismbbtrail
+; _ismbcalpha
+; _ismbcdigit
+; _ismbchira
+; _ismbckata
+; _ismbcl0
+; _ismbcl1
+; _ismbcl2
+; _ismbclegal
+; _ismbclower
+; _ismbcprint
+; _ismbcspace
+; _ismbcsymbol
+; _ismbcupper
+; _ismbslead
+; _ismbstrail
+; _lfind
+; _loaddll
+; _lrotl
+; _lrotr
+; _lsearch
+; _makepath
+; _matherr
+; _mbbtombc
+; _mbbtype
+; _mbccpy
+; _mbcjistojms
+; _mbcjmstojis
+; _mbclen
+; _mbctohira
+; _mbctokata
+; _mbctolower
+; _mbctombb
+; _mbctoupper
+; _mbctype
+; _mbsbtype
+; _mbscat
+; _mbscmp
+; _mbscpy
+; _mbscspn
+; _mbsdec
+; _mbsdup
+; _mbsicmp
+; _mbsinc
+; _mbslen
+; _mbslwr
+; _mbsnbcat
+; _mbsnbcmp
+; _mbsnbcnt
+; _mbsnbcpy
+; _mbsnbicmp
+; _mbsnbset
+; _mbsnccnt
+; _mbsncmp
+; _mbsncpy
+; _mbsnextc
+; _mbsnicmp
+; _mbsninc
+; _mbsnset
+; _mbspbrk
+; _mbsrchr
+; _mbsrev
+; _mbsset
+; _mbsspn
+; _mbsspnp
+; _mbsstr
+; _mbstrlen
+; _mbsupr
+; _onexit
+; _osver_dll
+; _osversion_dll
+; _pctype_dll
+; _purecall
+; _putw
+; _pwctype_dll
+; _rmtmp
+; _rotl
+; _rotr
+; _setsystime
+; _snprintf
+; _snwprintf
+; _splitpath
+; _strdate
+; _strdec
+; _strinc
+; _strncnt
+; _strnextc
+; _strninc
+; _strspnp
+; _strtime
+; _tempnam
+; _timezone_dll
+; _tzname
+; _tzset
+; _ultoa
+; _unloaddll
+; _vsnprintf
+; _vsnwprintf
+; _winmajor_dll
+; _winminor_dll
+; _winver_dll
+; _wtoi
+; _wtol
+;
+EXPORTS
+_CIacos
+_CIasin
+_CIatan
+_CIatan2
+_CIcos
+_CIcosh
+_CIexp
+_CIfmod
+_CIlog
+_CIlog10
+_CIpow
+_CIsin
+_CIsinh
+_CIsqrt
+_CItan
+_CItanh
+_HUGE_dll
+_XcptFilter
+__GetMainArgs
+__argc_dll
+__argv_dll
+__dllonexit
+__doserrno
+__fpecode
+__isascii
+__iscsym
+__iscsymf
+__mb_cur_max_dll
+__pxcptinfoptrs
+__threadhandle
+__threadid
+__toascii
+_abnormal_termination
+_access
+_acmdln_dll
+_aexit_rtn_dll
+_amsg_exit
+_assert
+_basemajor_dll
+_baseminor_dll
+_baseversion_dll
+_beep
+_beginthread
+_c_exit
+_cabs
+_cexit
+_cgets
+_chdir
+_chdrive
+_chgsign
+_chmod
+_chsize
+_clearfp
+_close
+_commit
+_commode_dll
+_control87
+_controlfp
+_copysign
+_cprintf
+_cpumode_dll
+_cputs
+_creat
+_cscanf
+_ctype
+_cwait
+_daylight_dll
+_dup
+_dup2
+_ecvt
+_endthread
+_environ_dll
+_eof
+_errno
+_except_handler2
+_execl
+_execle
+_execlp
+_execlpe
+_execv
+_execve
+_execvp
+_execvpe
+_exit
+_expand
+_fcloseall
+_fcvt
+_fdopen
+_fgetchar
+_fgetwchar
+_filbuf
+_fileinfo_dll
+_filelength
+_fileno
+_findclose
+_findfirst
+_findnext
+_finite
+_flsbuf
+_flushall
+_fmode_dll
+_fpclass
+_fpieee_flt
+_fpreset
+_fputchar
+_fputwchar
+_fsopen
+_fstat
+_ftime
+_ftol
+_fullpath
+_futime
+_gcvt
+_get_osfhandle
+_getch
+_getche
+_getcwd
+_getdcwd
+_getdiskfree
+_getdllprocaddr
+_getdrive
+_getdrives
+_getpid
+_getsystime
+_getw
+_global_unwind2
+_heapchk
+_heapmin
+_heapset
+_heapwalk
+_hypot
+_initterm
+_iob
+_isatty
+_isctype
+_ismbbalnum
+_ismbbalpha
+_ismbbgraph
+_ismbbkalnum
+_ismbbkana
+_ismbbkpunct
+_ismbblead
+_ismbbprint
+_ismbbpunct
+_ismbbtrail
+_ismbcalpha
+_ismbcdigit
+_ismbchira
+_ismbckata
+_ismbcl0
+_ismbcl1
+_ismbcl2
+_ismbclegal
+_ismbclower
+_ismbcprint
+_ismbcspace
+_ismbcsymbol
+_ismbcupper
+_ismbslead
+_ismbstrail
+_isnan
+_itoa
+_j0
+_j1
+_jn
+_kbhit
+_lfind
+_loaddll
+_local_unwind2
+_locking
+_logb
+_lrotl
+_lrotr
+_lsearch
+_lseek
+_ltoa
+_makepath
+_matherr
+_mbbtombc
+_mbbtype
+_mbccpy
+_mbcjistojms
+_mbcjmstojis
+_mbclen
+_mbctohira
+_mbctokata
+_mbctolower
+_mbctombb
+_mbctoupper
+_mbctype
+_mbsbtype
+_mbscat
+_mbschr
+_mbscmp
+_mbscpy
+_mbscspn
+_mbsdec
+_mbsdup
+_mbsicmp
+_mbsinc
+_mbslen
+_mbslwr
+_mbsnbcat
+_mbsnbcmp
+_mbsnbcnt
+_mbsnbcpy
+_mbsnbicmp
+_mbsnbset
+_mbsncat
+_mbsnccnt
+_mbsncmp
+_mbsncpy
+_mbsnextc
+_mbsnicmp
+_mbsninc
+_mbsnset
+_mbspbrk
+_mbsrchr
+_mbsrev
+_mbsset
+_mbsspn
+_mbsspnp
+_mbsstr
+_mbstok
+_mbstrlen
+_mbsupr
+_memccpy
+_memicmp
+_mkdir
+_mktemp
+_msize
+_nextafter
+_onexit
+_open
+_open_osfhandle
+_osmajor_dll
+_osminor_dll
+_osmode_dll
+_osver_dll
+_osversion_dll
+_pclose
+_pctype_dll
+_pgmptr_dll
+_pipe
+_popen
+_purecall
+_putch
+_putenv
+_putw
+_pwctype_dll
+_read
+_rmdir
+_rmtmp
+_rotl
+_rotr
+_scalb
+_searchenv
+_seterrormode
+_setjmp
+_setmode
+_setsystime
+_sleep
+_snprintf
+_snwprintf
+_sopen
+_spawnl
+_spawnle
+_spawnlp
+_spawnlpe
+_spawnv
+_spawnve
+_spawnvp
+_spawnvpe
+_splitpath
+_stat
+_statusfp
+_strcmpi
+_strdate
+_strdec
+_strdup
+_strerror
+_stricmp
+_stricoll
+_strinc
+_strlwr
+_strncnt
+_strnextc
+_strnicmp
+_strninc
+_strnset
+_strrev
+_strset
+_strspnp
+_strtime
+_strupr
+_swab
+_sys_errlist
+_sys_nerr_dll
+_tell
+_tempnam
+_timezone_dll
+_tolower
+_toupper
+_tzname
+_tzset
+_ultoa
+_umask
+_ungetch
+_unlink
+_unloaddll
+_utime
+_vsnprintf
+_vsnwprintf
+_wcsdup
+_wcsicmp
+_wcsicoll
+_wcslwr
+_wcsnicmp
+_wcsnset
+_wcsrev
+_wcsset
+_wcsupr
+_winmajor_dll
+_winminor_dll
+_winver_dll
+_write
+_wtoi
+_wtol
+_y0
+_y1
+_yn
+abort
+abs
+acos
+asctime
+asin
+atan
+atan2
+atexit
+atof
+atoi
+atol
+bsearch
+calloc
+ceil
+clearerr
+clock
+cos
+cosh
+ctime
+difftime
+div
+exit
+exp
+fabs
+fclose
+feof
+ferror
+fflush
+fgetc
+fgetpos
+fgets
+fgetwc
+floor
+fmod
+fopen
+fprintf
+fputc
+fputs
+fputwc
+fread
+free
+freopen
+frexp
+fscanf
+fseek
+fsetpos
+ftell
+fwprintf
+fwrite
+fwscanf
+getc
+getchar
+getenv
+gets
+gmtime
+is_wctype
+isalnum
+isalpha
+iscntrl
+isdigit
+isgraph
+isleadbyte
+islower
+isprint
+ispunct
+isspace
+isupper
+iswalnum
+iswalpha
+iswascii
+iswcntrl
+iswctype
+iswdigit
+iswgraph
+iswlower
+iswprint
+iswpunct
+iswspace
+iswupper
+iswxdigit
+isxdigit
+labs
+ldexp
+ldiv
+localeconv
+localtime
+log
+log10
+longjmp
+malloc
+mblen
+mbstowcs
+mbtowc
+memchr
+memcmp
+memcpy
+memmove
+memset
+mktime
+modf
+perror
+pow
+printf
+putc
+putchar
+puts
+qsort
+raise
+rand
+realloc
+remove
+rename
+rewind
+scanf
+setbuf
+setlocale
+setvbuf
+signal
+sin
+sinh
+sprintf
+sqrt
+srand
+sscanf
+strcat
+strchr
+strcmp
+strcoll
+strcpy
+strcspn
+strerror
+strftime
+strlen
+strncat
+strncmp
+strncpy
+strpbrk
+strrchr
+strspn
+strstr
+strtod
+strtok
+strtol
+strtoul
+strxfrm
+swprintf
+swscanf
+system
+tan
+tanh
+time
+tmpfile
+tmpnam
+tolower
+toupper
+towlower
+towupper
+ungetc
+ungetwc
+vfprintf
+vfwprintf
+vprintf
+vsprintf
+vswprintf
+vwprintf
+wcscat
+wcschr
+wcscmp
+wcscoll
+wcscpy
+wcscspn
+wcsftime
+wcslen
+wcsncat
+wcsncmp
+wcsncpy
+wcspbrk
+wcsrchr
+wcsspn
+wcsstr
+wcstod
+wcstok
+wcstol
+wcstombs
+wcstoul
+wcsxfrm
+wctomb
+wprintf
+wscanf
#include <io.h>
#include <windows.h>
-#include <libc/file.h>
+//#include <libc/file.h>
int close(int _fd)
CloseHandle(filehnd(_fd));
return __fileno_close(_fd);
-}
\ No newline at end of file
+}
#include <windows.h>
#include <io.h>
#include <string.h>
-#include <libc/file.h>
+
+#if 0
//UnixTimeToFileTime
//FileTimeToUnixTime
}
+#endif
#include <windows.h>
#include <io.h>
-#include <libc/file.h>
+//#include <libc/file.h>
#undef lseek
long lseek(int _fildes, long _offset, int _whence)
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
-#include <libc/file.h>
+//#include <libc/file.h>
#include <string.h>
#include <share.h>
+#if 0
+
typedef struct _fileno_modes_type
{
HANDLE hFile;
{
return __fileno_alloc((HANDLE)osfhandle, flags);
}
+#endif
*/
#include <io.h>
#include <windows.h>
-#include <libc/file.h>
int write(int _fd, const void *_buf,int _nbyte)
{
return -1;
}
return _wbyte;
-}
\ No newline at end of file
+}
#include <fcntl.h>
#include <string.h>
#include <windows.h>
-#include <libc/file.h>
+//#include <libc/file.h>
void UnixTimeToFileTime( time_t unix_time, FILETIME *filetime, DWORD remainder );
time_t FileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
#include <ddk/li.h>
#include <ddk/rtl.h>
+#define NDEBUG
+#include <kernel32/kernel32.h>
+
HANDLE STDCALL CreateFileA(LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
NULL,
0);
- dprintf("After create file");
+ DPRINT("After create file\n");
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return(FileHandle);
}
-#endif
\ No newline at end of file
+#endif
#include <windows.h>
-/* GLOBALS *******************************************************************/
-
+#define NDEBUG
+#include <kernel32/kernel32.h>
-WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
+/* GLOBALS *******************************************************************/
-WCHAR SystemDirectoryW[MAX_PATH];
-WCHAR WindowsDirectoryW[MAX_PATH];
+static WCHAR CurrentDirectoryW[MAX_PATH] = {0,};
+static WCHAR SystemDirectoryW[MAX_PATH];
+static WCHAR WindowsDirectoryW[MAX_PATH];
/* FUNCTIONS *****************************************************************/
{
UINT uSize;
- dprintf("CurrentDirectoryW %w\n",CurrentDirectoryW);
+ DPRINT("CurrentDirectoryW %w\n",CurrentDirectoryW);
if ( lpBuffer == NULL )
return 0;
if ( nBufferLength > uSize )
lstrcpynW(lpBuffer,CurrentDirectoryW,uSize);
- dprintf("GetCurrentDirectoryW() = %w\n",lpBuffer);
+ DPRINT("GetCurrentDirectoryW() = %w\n",lpBuffer);
return uSize;
}
{
UINT i;
- dprintf("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
+ DPRINT("SetCurrentDirectoryA(lpPathName %s)\n",lpPathName);
if ( lpPathName == NULL )
return FALSE;
}
CurrentDirectoryW[i] = 0;
- dprintf("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
+ DPRINT("CurrentDirectoryW = '%w'\n",CurrentDirectoryW);
return(TRUE);
}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS system libraries\r
- * FILE: lib/kernel32/file/find.c\r
- * PURPOSE: Find functions\r
- * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
- * UPDATE HISTORY:\r
- * Created 01/11/98\r
- */\r
-#include <windows.h>\r
-#include <wstring.h>\r
-#include <ddk/ntddk.h>\r
-\r
-typedef enum _FINDEX_INFO_LEVELS \r
-{ \r
- FindExSearchNameMatch, \r
- FindExSearchLimitToDirectories, \r
- FindExSearchLimitToDevices, \r
-\r
-} FINDEX_INFO_LEVELS ; \r
-\r
-typedef enum _FINDEX_SEARCH_OPS \r
-{ \r
- FindExInfoStandard \r
-\r
-} FINDEX_SEARCH_OPS; \r
-\r
-int wcharicmp ( WCHAR char1, WCHAR char2 );\r
-\r
-WINBOOL\r
-mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);\r
-\r
-HANDLE\r
-STDCALL\r
-FindFirstFileW(\r
- LPCWSTR lpFileName,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- );\r
-\r
-WINBOOL\r
-STDCALL\r
-FindNextFileW(\r
- HANDLE hFind,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- );\r
-\r
-HANDLE \r
-STDCALL\r
-FindFirstFileExA( \r
- LPCSTR lpFileName, \r
- FINDEX_INFO_LEVELS fInfoLevelId, \r
- LPVOID lpFindFileData, \r
- FINDEX_SEARCH_OPS fSearchOp, \r
- LPVOID lpSearchFilter, \r
- DWORD dwAdditionalFlags \r
- ); \r
- \r
-HANDLE \r
-STDCALL \r
-FindFirstFileExW( \r
- LPCWSTR lpFileName, \r
- FINDEX_INFO_LEVELS fInfoLevelId, \r
- LPVOID lpFindFileData, \r
- FINDEX_SEARCH_OPS fSearchOp, \r
- LPVOID lpSearchFilter, \r
- DWORD dwAdditionalFlags \r
- );\r
-\r
-typedef struct _FIND_FILE_INFO\r
-{\r
- ULONG Offset;\r
- PVOID SearchFilter;\r
- WCHAR FileName[MAX_PATH];\r
- WCHAR PathName[MAX_PATH];\r
- FILE_DIRECTORY_INFORMATION *FileDirectory;\r
-} FIND_FILE_INFO;\r
-\r
-typedef struct _WIN32_FIND_DATAW { \r
- DWORD dwFileAttributes; \r
- FILETIME ftCreationTime; \r
- FILETIME ftLastAccessTime; \r
- FILETIME ftLastWriteTime; \r
- DWORD nFileSizeHigh; \r
- DWORD nFileSizeLow; \r
- DWORD dwReserved0; \r
- DWORD dwReserved1; \r
- WCHAR cFileName[ MAX_PATH ]; \r
- WCHAR cAlternateFileName[ 14 ]; \r
-} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW; \r
-\r
-\r
-WINBOOL\r
-STDCALL\r
-FindClose(\r
- HANDLE hFind\r
- )\r
-{\r
- \r
- if ( hFind == NULL)\r
- return FALSE;\r
-\r
- \r
- HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);\r
- HeapFree(GetProcessHeap(),0,hFind);\r
- return TRUE;\r
-}\r
-\r
-\r
-HANDLE\r
-STDCALL\r
-FindFirstFileA(\r
- LPCSTR lpFileName,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- )\r
-{\r
- WIN32_FIND_DATA FindFileDataW;\r
- WCHAR FileNameW[MAX_PATH];\r
- ULONG i;\r
-\r
- i = 0;\r
- while ((*lpFileName)!=0 && i < MAX_PATH)\r
- {\r
- FileNameW[i] = *lpFileName;\r
- lpFileName++;\r
- i++;\r
- }\r
- FileNameW[i] = 0;\r
- FindFirstFileW(FileNameW,&FindFileDataW);\r
-\r
- // converteer FindFileDataW \r
-\r
-}\r
-\r
-HANDLE\r
-STDCALL\r
-FindFirstFileW(\r
- LPCWSTR lpFileName,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- )\r
-{\r
- return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);\r
-}\r
-\r
-WINBOOL\r
-STDCALL\r
-FindNextFileA(\r
- HANDLE hFind,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- )\r
-{\r
- WIN32_FIND_DATA FindFileDataW;\r
- FindNextFileW(hFind,&FindFileDataW);\r
- // converteer FindFileDataW \r
-}\r
-\r
-WINBOOL\r
-STDCALL\r
-FindNextFileW(\r
- HANDLE hFind,\r
- LPWIN32_FIND_DATA lpFindFileData\r
- )\r
-{\r
- int i;\r
- WCHAR *pNameRead;\r
- WCHAR FileName[MAX_PATH];\r
-\r
- FIND_FILE_INFO *FindPtr = hFind;\r
- FILE_DIRECTORY_INFORMATION *FileDirectory;\r
- \r
- if ( FindPtr == NULL )\r
- return FALSE;\r
- \r
- /* Try to find a file */\r
- FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;\r
- while ( FileDirectory->NextEntryOffset != 0 ) {\r
- \r
- pNameRead = FileDirectory->FileName;\r
- FindPtr->Offset += FileDirectory->NextEntryOffset;\r
- for(i=0;i<FileDirectory->FileNameLength;i++)\r
- dprintf("%c\n",(char)pNameRead[i]);\r
- if (mfs_regexp(pNameRead, FindPtr->FileName))\r
- { \r
- /* We found one! */\r
- if (FindPtr->PathName[0] != L'\0')\r
- {\r
- lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);\r
- lstrcatW(lpFindFileData->cFileName, L"/");\r
- lstrcatW(lpFindFileData->cFileName, pNameRead);\r
- }\r
- else\r
- \r
- lstrcpyW(lpFindFileData->cFileName, pNameRead);\r
-\r
- \r
- \r
- lstrcpyW(lpFindFileData->cAlternateFileName, L"");\r
- lpFindFileData->dwReserved0 = 0;\r
- lpFindFileData->dwReserved1 = 0;\r
- return TRUE;\r
- }\r
- FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;\r
- }\r
- return FALSE;\r
-}\r
-\r
-\r
-HANDLE \r
-STDCALL\r
-FindFirstFileExA( \r
- LPCSTR lpFileName, \r
- FINDEX_INFO_LEVELS fInfoLevelId, \r
- LPVOID lpFindFileData, \r
- FINDEX_SEARCH_OPS fSearchOp, \r
- LPVOID lpSearchFilter, \r
- DWORD dwAdditionalFlags \r
- )\r
-{\r
- WCHAR FileNameW[MAX_PATH];\r
- WIN32_FIND_DATAW FindFileDataW;\r
- FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);\r
- // conerteer FindFileDataW \r
-\r
-}\r
- \r
-HANDLE \r
-STDCALL \r
-FindFirstFileExW( \r
- LPCWSTR lpFileName, \r
- FINDEX_INFO_LEVELS fInfoLevelId, \r
- LPVOID lpFindFileData, \r
- FINDEX_SEARCH_OPS fSearchOp, \r
- LPVOID lpSearchFilter, \r
- DWORD dwAdditionalFlags \r
- )\r
-{\r
- NTSTATUS errCode;\r
- IO_STATUS_BLOCK IoStatusBlock; \r
- HANDLE FileHandle = NULL;\r
- FIND_FILE_INFO *hFind;\r
- WCHAR *FilePart;\r
- UNICODE_STRING FileNameString, PathNameString;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
-\r
-\r
- ACCESS_MASK DesiredAccess=FILE_READ_DATA;\r
- \r
- ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;\r
- ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;\r
- ULONG CreateDisposition=FILE_OPEN;\r
- ULONG CreateOptions=FILE_DIRECTORY_FILE;\r
-\r
-\r
- hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));\r
-\r
- hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);\r
-\r
-\r
-\r
- /* Try to find a path and a filename in the passed filename */\r
-\r
- lstrcpyW(hFind->PathName, lpFileName);\r
- FilePart = wcsrchr(hFind->PathName, '\\');\r
- \r
- if (FilePart == NULL){\r
- GetCurrentDirectory(MAX_PATH, hFind->PathName);\r
- lstrcpyW(hFind->FileName, lpFileName);\r
- }\r
- else {\r
- FilePart[0] = L'\0';\r
- lstrcpyW(hFind->FileName, &FilePart[1]);\r
- }\r
-\r
- hFind->Offset = 0;\r
- \r
-\r
- PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);\r
- PathNameString.Buffer = hFind->PathName;\r
- PathNameString.MaximumLength = FileNameString.Length;\r
- \r
-\r
- FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);\r
- FileNameString.Buffer = hFind->FileName;\r
- FileNameString.MaximumLength = FileNameString.Length;\r
-\r
-\r
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);\r
- ObjectAttributes.RootDirectory = NULL;\r
- ObjectAttributes.ObjectName = &PathNameString;\r
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;\r
- ObjectAttributes.SecurityDescriptor = NULL;\r
- ObjectAttributes.SecurityQualityOfService = NULL;\r
-\r
- \r
-\r
-\r
- \r
-\r
- errCode = NtCreateFile(\r
- &FileHandle,\r
- DesiredAccess,\r
- &ObjectAttributes,\r
- &IoStatusBlock,\r
- NULL, // AllocationSize\r
- FileAttributes,\r
- ShareAccess,\r
- CreateDisposition,\r
- CreateOptions,\r
- NULL, // EaBuffer\r
- 0); //\r
-\r
- if ( !NT_SUCCESS(errCode) ) {\r
- printf("%x\n",errCode);\r
- return NULL;\r
- }\r
-\r
- errCode = NtQueryDirectoryFile(\r
- FileHandle,\r
- NULL,\r
- NULL,\r
- NULL,\r
- &IoStatusBlock,\r
- hFind->FileDirectory,\r
- 8192,\r
- FileDirectoryInformation,\r
- FALSE,\r
- &FileNameString,\r
- FALSE\r
- );\r
- if ( !NT_SUCCESS(errCode) ) {\r
- printf("%x\n",errCode);\r
- return NULL;\r
- }\r
-\r
-\r
-\r
-\r
- if ( FindNextFileW(hFind,lpFindFileData) )\r
- return hFind;\r
- else {\r
- FindClose(hFind);\r
- return NULL;\r
- }\r
- return NULL;\r
-}\r
-\r
-/************************************************************************/\r
-WINBOOL\r
-mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)\r
-{\r
- /* The following code is provided by Tarang and I trust him...\r
- */\r
- LPWSTR lpTempFileName = (LPWSTR)lpFileName;\r
- LPWSTR lpTempFilter = (LPWSTR)lpFilter;\r
- WCHAR TempToken [ 2 ];\r
- WCHAR TempFilter [ 2 ];\r
- WINBOOL Matched = FALSE;\r
-\r
- if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||\r
- ( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )\r
- return 0L;\r
-\r
- if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )\r
- {\r
- wsprintf ( TempFilter, "*" );\r
- lpTempFilter = TempFilter;\r
- lpFilter = TempFilter;\r
- }\r
-\r
- while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )\r
- {\r
- memset ( TempToken, 0, sizeof ( TempToken ) );\r
- switch ( *lpTempFilter )\r
- {\r
- default:\r
- if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )\r
- {\r
- lpTempFileName = (LPWSTR)lpFileName;\r
- lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );\r
- if ( lpTempFilter )\r
- lpTempFilter+=sizeof(WCHAR);\r
- }\r
- else\r
- {\r
- lpTempFilter+=sizeof(WCHAR);\r
- lpTempFileName+=sizeof(WCHAR);\r
- switch ( *lpTempFilter )\r
- {\r
- default:\r
- break;\r
-\r
- case L'\0':\r
- case L' ':\r
- case L',':\r
- case L';':\r
- if ( ! *lpTempFileName )\r
- Matched = TRUE;\r
- break;\r
- }\r
- }\r
- break;\r
-\r
- case L'?':\r
- lpTempFilter+=sizeof(WCHAR);\r
- lpTempFileName+=sizeof(WCHAR);\r
- break;\r
-\r
- case L'*':\r
- lpTempFilter += sizeof(WCHAR);\r
- if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )\r
- Matched = TRUE;\r
- else\r
- {\r
- lpTempFilter+=sizeof(WCHAR);\r
- while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&\r
- ( ! Matched ) ) {\r
- lpTempFileName+= sizeof(WCHAR);\r
- Matched = mfs_regexp ( lpTempFileName, lpTempFilter );\r
- }\r
- if ( ( ! lpTempFileName ) && ( ! Matched ) )\r
- {\r
- lpTempFileName = (LPWSTR)lpFileName;\r
- lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );\r
- if ( lpTempFilter )\r
- lpTempFilter+=sizeof(WCHAR);\r
- }\r
- }\r
- break;\r
-\r
- case L'\0':\r
- case L' ':\r
- case L',':\r
- case L';':\r
- Matched = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- return (DWORD)Matched;\r
-\r
-\r
-}\r
-\r
-int wcharicmp ( WCHAR char1, WCHAR char2 )\r
-{\r
- WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ? \r
- char1 - L'a' + L'A' : char1;\r
- WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ? \r
- char2 - L'a' + L'A' : char2;\r
- return ( Char2 - Char1 );\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/kernel32/file/find.c
+ * PURPOSE: Find functions
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ * UPDATE HISTORY:
+ * Created 01/11/98
+ */
+#include <windows.h>
+#include <wstring.h>
+#include <ddk/ntddk.h>
+
+typedef enum _FINDEX_INFO_LEVELS
+{
+ FindExSearchNameMatch,
+ FindExSearchLimitToDirectories,
+ FindExSearchLimitToDevices,
+
+} FINDEX_INFO_LEVELS ;
+
+typedef enum _FINDEX_SEARCH_OPS
+{
+ FindExInfoStandard
+
+} FINDEX_SEARCH_OPS;
+
+int wcharicmp ( WCHAR char1, WCHAR char2 );
+
+WINBOOL
+mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter);
+
+HANDLE
+STDCALL
+FindFirstFileW(
+ LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData
+ );
+
+WINBOOL
+STDCALL
+FindNextFileW(
+ HANDLE hFind,
+ LPWIN32_FIND_DATA lpFindFileData
+ );
+
+HANDLE
+STDCALL
+FindFirstFileExA(
+ LPCSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags
+ );
+
+HANDLE
+STDCALL
+FindFirstFileExW(
+ LPCWSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags
+ );
+
+typedef struct _FIND_FILE_INFO
+{
+ ULONG Offset;
+ PVOID SearchFilter;
+ WCHAR FileName[MAX_PATH];
+ WCHAR PathName[MAX_PATH];
+ FILE_DIRECTORY_INFORMATION *FileDirectory;
+} FIND_FILE_INFO;
+
+typedef struct _WIN32_FIND_DATAW {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ WCHAR cFileName[ MAX_PATH ];
+ WCHAR cAlternateFileName[ 14 ];
+} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
+
+
+WINBOOL
+STDCALL
+FindClose(
+ HANDLE hFind
+ )
+{
+
+ if ( hFind == NULL)
+ return FALSE;
+
+
+ HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
+ HeapFree(GetProcessHeap(),0,hFind);
+ return TRUE;
+}
+
+
+HANDLE
+STDCALL
+FindFirstFileA(
+ LPCSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ WIN32_FIND_DATA FindFileDataW;
+ WCHAR FileNameW[MAX_PATH];
+ ULONG i;
+
+ i = 0;
+ while ((*lpFileName)!=0 && i < MAX_PATH)
+ {
+ FileNameW[i] = *lpFileName;
+ lpFileName++;
+ i++;
+ }
+ FileNameW[i] = 0;
+ FindFirstFileW(FileNameW,&FindFileDataW);
+
+ // converteer FindFileDataW
+
+}
+
+HANDLE
+STDCALL
+FindFirstFileW(
+ LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ return FindFirstFileExW(lpFileName,FindExInfoStandard,lpFindFileData,FindExSearchNameMatch,NULL,0);
+}
+
+WINBOOL
+STDCALL
+FindNextFileA(
+ HANDLE hFind,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ WIN32_FIND_DATA FindFileDataW;
+ FindNextFileW(hFind,&FindFileDataW);
+ // converteer FindFileDataW
+}
+
+WINBOOL
+STDCALL
+FindNextFileW(
+ HANDLE hFind,
+ LPWIN32_FIND_DATA lpFindFileData
+ )
+{
+ int i;
+ WCHAR *pNameRead;
+ WCHAR FileName[MAX_PATH];
+
+ FIND_FILE_INFO *FindPtr = hFind;
+ FILE_DIRECTORY_INFORMATION *FileDirectory;
+
+ if ( FindPtr == NULL )
+ return FALSE;
+
+ /* Try to find a file */
+ FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
+ while ( FileDirectory->NextEntryOffset != 0 ) {
+
+ pNameRead = FileDirectory->FileName;
+ FindPtr->Offset += FileDirectory->NextEntryOffset;
+ for(i=0;i<FileDirectory->FileNameLength;i++)
+ dprintf("%c\n",(char)pNameRead[i]);
+ if (mfs_regexp(pNameRead, FindPtr->FileName))
+ {
+ /* We found one! */
+ if (FindPtr->PathName[0] != L'\0')
+ {
+ lstrcpyW(lpFindFileData->cFileName, FindPtr->PathName);
+ lstrcatW(lpFindFileData->cFileName, L"/");
+ lstrcatW(lpFindFileData->cFileName, pNameRead);
+ }
+ else
+
+ lstrcpyW(lpFindFileData->cFileName, pNameRead);
+
+
+
+ lstrcpyW(lpFindFileData->cAlternateFileName, L"");
+ lpFindFileData->dwReserved0 = 0;
+ lpFindFileData->dwReserved1 = 0;
+ return TRUE;
+ }
+ FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
+ }
+ return FALSE;
+}
+
+
+HANDLE
+STDCALL
+FindFirstFileExA(
+ LPCSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags
+ )
+{
+ WCHAR FileNameW[MAX_PATH];
+ WIN32_FIND_DATAW FindFileDataW;
+ FindFirstFileExW(FileNameW,fInfoLevelId,&FindFileDataW,fSearchOp,lpSearchFilter,dwAdditionalFlags);
+ // conerteer FindFileDataW
+
+}
+
+HANDLE
+STDCALL
+FindFirstFileExW(
+ LPCWSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags
+ )
+{
+ NTSTATUS errCode;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE FileHandle = NULL;
+ FIND_FILE_INFO *hFind;
+ WCHAR *FilePart;
+ UNICODE_STRING FileNameString, PathNameString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+
+ ACCESS_MASK DesiredAccess=FILE_READ_DATA;
+
+ ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
+ ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ ULONG CreateDisposition=FILE_OPEN;
+ ULONG CreateOptions=FILE_DIRECTORY_FILE;
+
+
+ hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
+
+ hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
+
+
+
+ /* Try to find a path and a filename in the passed filename */
+
+ lstrcpyW(hFind->PathName, lpFileName);
+ FilePart = wcsrchr(hFind->PathName, '\\');
+
+ if (FilePart == NULL){
+ GetCurrentDirectory(MAX_PATH, hFind->PathName);
+ lstrcpyW(hFind->FileName, lpFileName);
+ }
+ else {
+ FilePart[0] = L'\0';
+ lstrcpyW(hFind->FileName, &FilePart[1]);
+ }
+
+ hFind->Offset = 0;
+
+
+ PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
+ PathNameString.Buffer = hFind->PathName;
+ PathNameString.MaximumLength = FileNameString.Length;
+
+
+ FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
+ FileNameString.Buffer = hFind->FileName;
+ FileNameString.MaximumLength = FileNameString.Length;
+
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = &PathNameString;
+ ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+
+
+
+
+
+ errCode = NtCreateFile(
+ &FileHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL, // AllocationSize
+ FileAttributes,
+ ShareAccess,
+ CreateDisposition,
+ CreateOptions,
+ NULL, // EaBuffer
+ 0); //
+
+ if ( !NT_SUCCESS(errCode) ) {
+ printf("%x\n",errCode);
+ return NULL;
+ }
+
+ errCode = NtQueryDirectoryFile(
+ FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ hFind->FileDirectory,
+ 8192,
+ FileDirectoryInformation,
+ FALSE,
+ &FileNameString,
+ FALSE
+ );
+ if ( !NT_SUCCESS(errCode) ) {
+ printf("%x\n",errCode);
+ return NULL;
+ }
+
+
+
+
+ if ( FindNextFileW(hFind,lpFindFileData) )
+ return hFind;
+ else {
+ FindClose(hFind);
+ return NULL;
+ }
+ return NULL;
+}
+
+/************************************************************************/
+WINBOOL
+mfs_regexp(LPCWSTR lpFileName,LPCWSTR lpFilter)
+{
+ /* The following code is provided by Tarang and I trust him...
+ */
+ LPWSTR lpTempFileName = (LPWSTR)lpFileName;
+ LPWSTR lpTempFilter = (LPWSTR)lpFilter;
+ WCHAR TempToken [ 2 ];
+ WCHAR TempFilter [ 2 ];
+ WINBOOL Matched = FALSE;
+
+ if ( ( ! (LPWSTR)lpFileName ) || ( ! *(LPWSTR)lpFileName ) ||
+ ( ! (LPWSTR)lpFilter ) || ( ! *(LPWSTR)lpFilter ) )
+ return 0L;
+
+ if ( ! lstrcmpW ( ( LPSTR )lpFilter, "*.*" ) )
+ {
+ wsprintf ( TempFilter, "*" );
+ lpTempFilter = TempFilter;
+ lpFilter = TempFilter;
+ }
+
+ while ( ( lpTempFilter ) && ( *lpTempFilter ) && ( ! Matched ) )
+ {
+ memset ( TempToken, 0, sizeof ( TempToken ) );
+ switch ( *lpTempFilter )
+ {
+ default:
+ if ( wcharicmp ( *lpTempFileName, *lpTempFilter ) )
+ {
+ lpTempFileName = (LPWSTR)lpFileName;
+ lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
+ if ( lpTempFilter )
+ lpTempFilter+=sizeof(WCHAR);
+ }
+ else
+ {
+ lpTempFilter+=sizeof(WCHAR);
+ lpTempFileName+=sizeof(WCHAR);
+ switch ( *lpTempFilter )
+ {
+ default:
+ break;
+
+ case L'\0':
+ case L' ':
+ case L',':
+ case L';':
+ if ( ! *lpTempFileName )
+ Matched = TRUE;
+ break;
+ }
+ }
+ break;
+
+ case L'?':
+ lpTempFilter+=sizeof(WCHAR);
+ lpTempFileName+=sizeof(WCHAR);
+ break;
+
+ case L'*':
+ lpTempFilter += sizeof(WCHAR);
+ if ( ! ( TempToken [ 0 ] = *( lpTempFilter ) ) )
+ Matched = TRUE;
+ else
+ {
+ lpTempFilter+=sizeof(WCHAR);
+ while ( ( lpTempFileName = wcspbrk ( lpTempFileName, TempToken ) ) &&
+ ( ! Matched ) ) {
+ lpTempFileName+= sizeof(WCHAR);
+ Matched = mfs_regexp ( lpTempFileName, lpTempFilter );
+ }
+ if ( ( ! lpTempFileName ) && ( ! Matched ) )
+ {
+ lpTempFileName = (LPWSTR)lpFileName;
+ lpTempFilter = wcspbrk ( lpTempFilter, L" ,;" );
+ if ( lpTempFilter )
+ lpTempFilter+=sizeof(WCHAR);
+ }
+ }
+ break;
+
+ case L'\0':
+ case L' ':
+ case L',':
+ case L';':
+ Matched = TRUE;
+ break;
+ }
+ }
+
+ return (DWORD)Matched;
+
+
+}
+
+int wcharicmp ( WCHAR char1, WCHAR char2 )
+{
+ WCHAR Char1 = ( L'a' <= char1 ) && ( char1 <= L'z' ) ?
+ char1 - L'a' + L'A' : char1;
+ WCHAR Char2 = ( L'a' <= char2 ) && ( char2 <= L'z' ) ?
+ char2 - L'a' + L'A' : char2;
+ return ( Char2 - Char1 );
+}
* UPDATE HISTORY:
* Created 01/11/98
*/
+
+/* INCLUDES *****************************************************************/
+
#include <windows.h>
#include <wstring.h>
-#include <string.h>
#include <ddk/ntddk.h>
+#define NDEBUG
+#include <kernel32/kernel32.h>
+/* TYPES ********************************************************************/
-
-
-
-
-
-typedef struct _FIND_FILE_INFO
+typedef struct _KERNEL32_FIND_FILE_DATA
{
- ULONG Offset;
- WCHAR PathName[MAX_PATH];
- WCHAR FileName[MAX_PATH];
- FILE_DIRECTORY_INFORMATION *FileDirectory;
-} FIND_FILE_INFO;
+ HANDLE DirectoryHandle;
+ FILE_DIRECTORY_INFORMATION FileInfo;
+ WCHAR FileNameExtra[MAX_PATH];
+ UNICODE_STRING PatternStr;
+} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
-typedef struct _NOTIFY_INFO
-{
- HANDLE Event;
- HANDLE FileHandle;
- DWORD dwNotifyFilter;
- WINBOOL bWatchSubtree;
-} NOTIFY_INFO;
-
-
-
-
-typedef struct _WIN32_FIND_DATAW {
+typedef struct _WIN32_FIND_DATA_UNICODE {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
DWORD dwReserved1;
WCHAR cFileName[ MAX_PATH ];
WCHAR cAlternateFileName[ 14 ];
-} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW, *PWIN32_FIND_DATAW;
-
+} WIN32_FIND_DATA_UNICODE, *PWIN32_FIND_DATA_UNICODE;
-WINBOOL
-STDCALL
-FindClose(
- HANDLE hFind
- )
-{
-
- if ( hFind == NULL)
- return FALSE;
- if ( hFind == (HANDLE)-1)
- return FALSE;
-
- HeapFree(GetProcessHeap(),0,((FIND_FILE_INFO *)hFind)->FileDirectory);
- HeapFree(GetProcessHeap(),0,hFind);
- return TRUE;
-}
+typedef struct _WIN32_FIND_DATA_ASCII {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ CHAR cFileName[ MAX_PATH ];
+ CHAR cAlternateFileName[ 14 ];
+} WIN32_FIND_DATA_ASCII, *PWIN32_FIND_DATA_ASCII;
+/* FUNCTIONS *****************************************************************/
-HANDLE
-STDCALL
-FindFirstFileA(
- LPCSTR lpFileName,
- LPWIN32_FIND_DATA lpFindFileData
- )
+WINBOOL STDCALL InternalFindNextFile(HANDLE hFindFile,
+ LPWIN32_FIND_DATA lpFindFileData)
{
- WIN32_FIND_DATAW FindFileDataW;
- WCHAR FileNameW[MAX_PATH];
- ULONG i;
- HANDLE hFind;
-
- i = 0;
- while ((*lpFileName)!=0 && i < MAX_PATH)
- {
- FileNameW[i] = *lpFileName;
- lpFileName++;
- i++;
- }
- FileNameW[i] = 0;
- hFind = FindFirstFileW(FileNameW,(WIN32_FIND_DATA *)&FindFileDataW);
-
- lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
- memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
- memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
- memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
- lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
- lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
- lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
- lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
- i = 0;
- while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
- {
- lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
- i++;
- }
- lpFindFileData->cFileName[i] = 0;
-
- i = 0;
- while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
- {
- lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
- i++;
- }
- lpFindFileData->cAlternateFileName[i] = 0;
-
-
- return hFind;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ PKERNEL32_FIND_FILE_DATA IData;
+
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
+
+ Status = NtQueryDirectoryFile(IData->DirectoryHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ (PVOID)&IData->FileInfo,
+ sizeof(IData->FileInfo) +
+ sizeof(IData->FileNameExtra),
+ FileDirectoryInformation,
+ TRUE,
+ &(IData->PatternStr),
+ FALSE);
+ DPRINT("Found %w\n",IData->FileInfo.FileName);
+ lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
+ if (Status != STATUS_SUCCESS)
+ {
+ return(FALSE);
+ }
+ return(TRUE);
}
-HANDLE
-STDCALL
-FindFirstFileW(
- LPCWSTR lpFileName,
- LPWIN32_FIND_DATA lpFindFileData
- )
+HANDLE STDCALL InternalFindFirstFile(LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData)
{
- NTSTATUS errCode;
- IO_STATUS_BLOCK IoStatusBlock;
- HANDLE FileHandle = NULL;
- FIND_FILE_INFO *hFind;
- WCHAR *FilePart;
- UNICODE_STRING FileNameString, PathNameString;
- OBJECT_ATTRIBUTES ObjectAttributes;
-
-
- ACCESS_MASK DesiredAccess=FILE_READ_DATA;
-
- ULONG FileAttributes=FILE_ATTRIBUTE_DIRECTORY;
- ULONG ShareAccess=FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- ULONG CreateDisposition=FILE_OPEN;
- ULONG CreateOptions=FILE_DIRECTORY_FILE;
-
-
- hFind = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,sizeof(FIND_FILE_INFO));
-
- hFind->FileDirectory = HeapAlloc(GetProcessHeap(),HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,8192);
-
-
-
- /* Try to find a path and a filename in the passed filename */
-
- lstrcpyW(hFind->PathName, lpFileName);
- FilePart = wcsrchr(hFind->PathName, '\\');
-
- if (FilePart == NULL){
- GetCurrentDirectoryW(MAX_PATH, hFind->PathName);
- lstrcpyW(hFind->FileName, lpFileName);
- }
- else {
- lstrcpyW(hFind->FileName, &FilePart[1]);
- }
-
- hFind->Offset = 0;
-
-
- PathNameString.Length = lstrlenW(hFind->PathName)*sizeof(WCHAR);
- PathNameString.Buffer = hFind->PathName;
- PathNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
+ WCHAR CurrentDirectory[MAX_PATH];
+ WCHAR Pattern[MAX_PATH];
+ WCHAR Directory[MAX_PATH];
+ PWSTR End;
+ PKERNEL32_FIND_FILE_DATA IData;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DirectoryNameStr;
+ IO_STATUS_BLOCK IoStatusBlock;
-
- FileNameString.Length = lstrlenW(hFind->FileName)*sizeof(WCHAR);
- FileNameString.Buffer = hFind->FileName;
- FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
-
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = &PathNameString;
- ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
-
-
-
-
-
- errCode = NtCreateFile(
- &FileHandle,
- DesiredAccess,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FileAttributes,
- ShareAccess,
- CreateDisposition,
- CreateOptions,
- NULL,
- 0); //
-
- if ( !NT_SUCCESS(errCode) ) {
-
- return NULL;
- }
-
- errCode = NtQueryDirectoryFile(
- FileHandle,
- NULL,
- NULL,
- NULL,
- &IoStatusBlock,
- hFind->FileDirectory,
- 8192,
- FileDirectoryInformation,
- FALSE,
- &FileNameString,
- FALSE
- );
- if ( !NT_SUCCESS(errCode) ) {
- // printf("%x\n",errCode);
- return NULL;
- }
-
-
-
-
- if ( FindNextFileW(hFind,lpFindFileData) )
- return hFind;
- else {
- FindClose(hFind);
- return NULL;
- }
- return NULL;
+ DPRINT("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
+ lpFileName, lpFindFileData);
+
+ GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
+ Directory[0] = '\\';
+ Directory[1] = '?';
+ Directory[2] = '?';
+ Directory[3] = '\\';
+ Directory[4] = 0;
+ DPRINT("Directory %w\n",Directory);
+ wcscat(Directory, CurrentDirectory);
+ DPRINT("Directory %w\n",Directory);
+ wcscat(Directory, lpFileName);
+ DPRINT("Directory %w\n",Directory);
+ End = wcsrchr(Directory, '\\');
+ *End = 0;
+
+ wcscpy(Pattern, End+1);
+ *(End+1) = 0;
+ *End = '\\';
+
+ DPRINT("Directory %w Pattern %w\n",Directory,Pattern);
+
+ IData = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(KERNEL32_FIND_FILE_DATA));
+
+ RtlInitUnicodeString(&DirectoryNameStr, Directory);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirectoryNameStr,
+ 0,
+ NULL,
+ NULL);
+
+ if (ZwOpenFile(&IData->DirectoryHandle,
+ FILE_LIST_DIRECTORY,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_OPEN_IF,
+ OPEN_EXISTING)!=STATUS_SUCCESS)
+ {
+ return(NULL);
+ }
+
+ RtlInitUnicodeString(&(IData->PatternStr), Pattern);
+
+ NtQueryDirectoryFile(IData->DirectoryHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ (PVOID)&IData->FileInfo,
+ sizeof(IData->FileInfo) +
+ sizeof(IData->FileNameExtra),
+ FileDirectoryInformation,
+ TRUE,
+ &(IData->PatternStr),
+ FALSE);
+ DPRINT("Found %w\n",IData->FileInfo.FileName);
+
+ lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
+ return(IData);
}
-WINBOOL
-STDCALL
-FindNextFileA(
- HANDLE hFind,
- LPWIN32_FIND_DATA lpFindFileData
- )
+HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
{
- WIN32_FIND_DATAW FindFileDataW;
- ULONG i;
-
-
- hFind = FindNextFileW(hFind,(WIN32_FIND_DATA *)&FindFileDataW);
-
- lpFindFileData->dwFileAttributes = FindFileDataW.dwFileAttributes;
- memcpy(&lpFindFileData->ftCreationTime,&FindFileDataW.ftCreationTime,sizeof(FILETIME));
- memcpy(&lpFindFileData->ftLastAccessTime,&FindFileDataW.ftLastAccessTime,sizeof(FILETIME));
- memcpy(&lpFindFileData->ftLastWriteTime,&FindFileDataW.ftLastWriteTime,sizeof(FILETIME));
- lpFindFileData->nFileSizeHigh = FindFileDataW.nFileSizeHigh;
- lpFindFileData->nFileSizeLow = FindFileDataW.nFileSizeLow;
- lpFindFileData->dwReserved0= FindFileDataW.dwReserved0;
- lpFindFileData->dwReserved1= FindFileDataW.dwReserved1;
- i = 0;
- while ((lpFindFileData->cFileName[i])!=0 && i < MAX_PATH)
- {
- lpFindFileData->cFileName[i] = (char)FindFileDataW.cFileName[i];
- i++;
- }
- lpFindFileData->cFileName[i] = 0;
+ WCHAR lpFileNameW[MAX_PATH];
+ ULONG i;
+ PKERNEL32_FIND_FILE_DATA IData;
+ PWIN32_FIND_DATA_ASCII Ret;
+
+ DPRINT("FindFirstFileA(lpFileName %s, lpFindFileData %x)\n",
+ lpFileName,lpFindFileData);
+
+ i = 0;
+ while (lpFileName[i]!=0)
+ {
+ lpFileNameW[i] = lpFileName[i];
+ i++;
+ }
+ lpFileNameW[i] = 0;
+
+ IData = InternalFindFirstFile(lpFileNameW,lpFindFileData);
+ if (IData == NULL)
+ {
+ DPRINT("Failing request\n");
+ return(NULL);
+ }
+
+ Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
- i = 0;
- while ((lpFindFileData->cAlternateFileName[i])!=0 && i < 14)
- {
- lpFindFileData->cAlternateFileName[i] = (char)FindFileDataW.cAlternateFileName[i];
- i++;
- }
- lpFindFileData->cAlternateFileName[i] = 0;
-
-
- return hFind;
+ for (i=0; i<IData->FileInfo.FileNameLength; i++)
+ {
+ Ret->cFileName[i] = IData->FileInfo.FileName[i];
+ }
+ Ret->cFileName[i] = 0;
+
+ return(IData);
}
-WINBOOL
-STDCALL
-FindNextFileW(
- HANDLE hFind,
- LPWIN32_FIND_DATA lpFindFileData
- )
+WINBOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{
-
-
- LPWIN32_FIND_DATAW lpFindFileDataW = (LPWIN32_FIND_DATAW)lpFindFileData;
-
- FIND_FILE_INFO *FindPtr = hFind;
- FILE_DIRECTORY_INFORMATION *FileDirectory=NULL;
-
- if ( FindPtr == NULL )
- return FALSE;
- if ( FileDirectory->NextEntryOffset == 0 )
- return FALSE;
-
- /* Try to find a file */
- FileDirectory = FindPtr->Offset + FindPtr->FileDirectory;
-
-
-
-
- FindPtr->Offset += FileDirectory->NextEntryOffset;
-
- /* We found one! */
- if (FindPtr->PathName[0] != L'\0')
- {
- wcscpy(lpFindFileDataW->cFileName, FindPtr->PathName);
- wcscat(lpFindFileDataW->cFileName, L"\\");
- wcscat(lpFindFileDataW->cFileName, FileDirectory->FileName);
- }
- else
- wcscpy(lpFindFileDataW->cFileName, FileDirectory->FileName);
-
-
-
- wcscpy(lpFindFileDataW->cAlternateFileName, L"");
- lpFindFileData->dwReserved0 = 0;
- lpFindFileData->dwReserved1 = 0;
- return TRUE;
-
+ PWIN32_FIND_DATA_ASCII Ret;
+ PKERNEL32_FIND_FILE_DATA IData;
+ ULONG i;
+
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
+ if (IData == NULL)
+ {
+ return(FALSE);
+ }
+
+ if (!InternalFindNextFile(hFindFile, lpFindFileData))
+ {
+ return(FALSE);
+ }
+
+ Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
+
+ for (i=0; i<IData->FileInfo.FileNameLength; i++)
+ {
+ Ret->cFileName[i] = IData->FileInfo.FileName[i];
+ }
+ Ret->cFileName[i] = 0;
+
+ return(TRUE);
}
-
-
-
-
-
-HANDLE
-STDCALL
-FindFirstChangeNotificationA(
- LPCSTR lpPathName,
- WINBOOL bWatchSubtree,
- DWORD dwNotifyFilter
- )
+BOOL FindClose(HANDLE hFindFile)
{
- ULONG i;
-
- WCHAR PathNameW[MAX_PATH];
-
-
-
-
- i = 0;
- while ((*lpPathName)!=0 && i < MAX_PATH)
- {
- PathNameW[i] = *lpPathName;
- lpPathName++;
- i++;
- }
- PathNameW[i] = 0;
- return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
-
+ PKERNEL32_FIND_FILE_DATA IData;
+
+ dprintf("FindClose(hFindFile %x)\n",hFindFile);
+
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
+ NtClose(IData->DirectoryHandle);
+ HeapFree(GetProcessHeap(), 0, IData);
+ return(TRUE);
}
-HANDLE
-STDCALL
-FindFirstChangeNotificationW(
- LPCWSTR lpPathName,
- WINBOOL bWatchSubtree,
- DWORD dwNotifyFilter
- )
+HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData)
{
- NTSTATUS errCode;
-
-
- IO_STATUS_BLOCK IoStatusBlock;
- NOTIFY_INFO *NotifyHandle;
- WCHAR Buffer[100];
- ULONG BufferSize = 100;
-
- NotifyHandle = HeapAlloc(GetProcessHeap(),0,sizeof(NOTIFY_INFO));
-
- NotifyHandle->Event = CreateEventW(NULL,FALSE,FALSE,NULL);
- NotifyHandle->FileHandle = CreateFileW(lpPathName,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
+ PWIN32_FIND_DATA_UNICODE Ret;
+ PKERNEL32_FIND_FILE_DATA IData;
+
+ IData = InternalFindFirstFile(lpFileName,lpFindFileData);
+ Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
- NotifyHandle->dwNotifyFilter = dwNotifyFilter;
- NotifyHandle->bWatchSubtree = bWatchSubtree;
+ memcpy(Ret->cFileName, IData->FileInfo.FileName,
+ IData->FileInfo.FileNameLength);
+ memset(Ret->cAlternateFileName, 0, 14);
- errCode = NtNotifyChangeDirectoryFile(
- NotifyHandle->FileHandle,
- NotifyHandle->Event,
- NULL,
- NULL,
- &IoStatusBlock,
- Buffer,
- BufferSize,
- NotifyHandle->dwNotifyFilter,
- NotifyHandle->bWatchSubtree
- );
- return NotifyHandle;
+ return(IData);
}
-WINBOOL
-STDCALL
-FindNextChangeNotification(
- HANDLE hChangeHandle
- )
+WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
+ LPWIN32_FIND_DATA lpFindFileData)
{
- NTSTATUS errCode;
+ PWIN32_FIND_DATA_UNICODE Ret;
+ PKERNEL32_FIND_FILE_DATA IData;
-
- IO_STATUS_BLOCK IoStatusBlock;
- NOTIFY_INFO *NotifyHandle = hChangeHandle;
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
+ if (!InternalFindNextFile(hFindFile, lpFindFileData))
+ {
+ return(FALSE);
+ }
- WCHAR Buffer[100];
- ULONG BufferSize = 100;
- EVENT_BASIC_INFORMATION EventBasic;
- ULONG ReturnLength;
-
-
+ Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
- NtQueryEvent(NotifyHandle->Event,EventBasicInformation,&EventBasic,sizeof(EVENT_BASIC_INFORMATION),&ReturnLength);
-
- if ( EventBasic.Signaled == TRUE ) {
- ResetEvent(NotifyHandle->Event);
- return TRUE;
- }
+ memcpy(Ret->cFileName, IData->FileInfo.FileName,
+ IData->FileInfo.FileNameLength);
+ memset(Ret->cAlternateFileName, 0, 14);
- errCode = NtNotifyChangeDirectoryFile(
- NotifyHandle->FileHandle,
- NotifyHandle->Event,
- NULL,
- NULL,
- &IoStatusBlock,
- Buffer,
- BufferSize,
- NotifyHandle->dwNotifyFilter,
- (BOOLEAN)NotifyHandle->bWatchSubtree
- );
-
- return FALSE;
+ return(TRUE);
}
-
-WINBOOL
-STDCALL
-FindCloseChangeNotification(
- HANDLE hChangeHandle
- )
-{
- HeapFree(GetProcessHeap(),0,hChangeHandle);
- return TRUE;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS system libraries\r
- * FILE: lib/kernel32/file/find.c\r
- * PURPOSE: Find functions\r
- * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)\r
- * UPDATE HISTORY:\r
- * Created 01/11/98\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <windows.h>\r
-#include <wstring.h>\r
-#include <ddk/ntddk.h>\r
-\r
-/* TYPES ********************************************************************/\r
-\r
-typedef struct _KERNEL32_FIND_FILE_DATA;\r
-{\r
- HANDLE DirectoryHandle;\r
- FILE_DIRECTORY_INFORMATION FileInfo;\r
-} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- WCHAR lpFileNameW[MAX_PATH];\r
- ULONG i;\r
- \r
- i = 0;\r
- while (lpFileName[i]!=0)\r
- {\r
- lpFileName[i] = lpFileName[i];\r
- i++;\r
- }\r
- \r
- return(FindFirstFileW(lpFileName,lpFindFileData));\r
-}\r
-\r
-BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- return(FindNextFileW(hFindFile, lpFindFileData));\r
-}\r
-\r
-BOOL FindClose(HANDLE hFindFile)\r
-{\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- \r
- IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;\r
- NtClose(IData->DirectoryHandle);\r
- HeapFree(IData);\r
-}\r
-\r
-HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName, \r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
- WCHAR CurrentDirectory[MAX_PATH];\r
- WCHAR Pattern[MAX_PATH];\r
- WCHAR Directory[MAX_PATH];\r
- PWSTR End;\r
- PKERNEL32_FIND_FILE_DATA IData;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- UNICODE_STRING DirectoryNameStr;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- \r
- dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",\r
- lpFileName, lpFindFileData);\r
- \r
- GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);\r
- Directory[0] = '\\';\r
- Directory[1] = '?';\r
- Directory[2] = '?';\r
- Directory[3] = '\\';\r
- Directory[4] = 0;\r
- wstrcat(Directory, CurrentDirectory);\r
- wstrcat(Directory, lpFileName);\r
- End = wstrchr(Directory, '\\');\r
- *End = 0;\r
- \r
- wstrcpy(Pattern, End+1);\r
- \r
- dprintf("Directory %w End %w\n",Directory,End);\r
- \r
- IData = HeapAlloc(GetProcessHeap(), \r
- HEAP_ZERO_MEMORY, \r
- sizeof(KERNEL32_FIND_FILE_DATA));\r
- \r
- RtlInitUnicodeString(&DirectoryNameStr, Directory);\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- &DirectoryNameStr,\r
- 0,\r
- NULL,\r
- NULL);\r
- \r
- if (ZwOpenFile(&IData->DirectoryHandle,\r
- FILE_TRAVERSE,\r
- &ObjectAttributes,\r
- 0,\r
- OPEN_EXISTING)!=STATUS_SUCCESS)\r
- {\r
- return(NULL);\r
- }\r
- \r
- NtQueryDirectoryFile(IData->DirectoryHandle,\r
- NULL,\r
- NULL,\r
- NULL,\r
- &IoStatusBlock,\r
- &IData->FileInfo,\r
- sizeof(IData->FileInfo),\r
- FileDirectoryInformation,\r
- TRUE,\r
- Pattern,\r
- FALSE);\r
- \r
- return(IData);\r
-}\r
-\r
-WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,\r
- LPWIN32_FIND_DATA lpFindFileData)\r
-{\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS system libraries
+ * FILE: lib/kernel32/file/find.c
+ * PURPOSE: Find functions
+ * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ * UPDATE HISTORY:
+ * Created 01/11/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <windows.h>
+#include <wstring.h>
+#include <ddk/ntddk.h>
+
+/* TYPES ********************************************************************/
+
+typedef struct _KERNEL32_FIND_FILE_DATA;
+{
+ HANDLE DirectoryHandle;
+ FILE_DIRECTORY_INFORMATION FileInfo;
+} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
+
+/* FUNCTIONS *****************************************************************/
+
+HANDLE FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData)
+{
+ WCHAR lpFileNameW[MAX_PATH];
+ ULONG i;
+
+ i = 0;
+ while (lpFileName[i]!=0)
+ {
+ lpFileName[i] = lpFileName[i];
+ i++;
+ }
+
+ return(FindFirstFileW(lpFileName,lpFindFileData));
+}
+
+BOOLEAN FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
+{
+ return(FindNextFileW(hFindFile, lpFindFileData));
+}
+
+BOOL FindClose(HANDLE hFindFile)
+{
+ PKERNEL32_FIND_FILE_DATA IData;
+
+ IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
+ NtClose(IData->DirectoryHandle);
+ HeapFree(IData);
+}
+
+HANDLE STDCALL FindFirstFileW(LPCWSTR lpFileName,
+ LPWIN32_FIND_DATA lpFindFileData)
+{
+ WCHAR CurrentDirectory[MAX_PATH];
+ WCHAR Pattern[MAX_PATH];
+ WCHAR Directory[MAX_PATH];
+ PWSTR End;
+ PKERNEL32_FIND_FILE_DATA IData;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DirectoryNameStr;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ dprintf("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
+ lpFileName, lpFindFileData);
+
+ GetCurrentDirectoryW(MAX_PATH, CurrentDirectory);
+ Directory[0] = '\\';
+ Directory[1] = '?';
+ Directory[2] = '?';
+ Directory[3] = '\\';
+ Directory[4] = 0;
+ wstrcat(Directory, CurrentDirectory);
+ wstrcat(Directory, lpFileName);
+ End = wstrchr(Directory, '\\');
+ *End = 0;
+
+ wstrcpy(Pattern, End+1);
+
+ dprintf("Directory %w End %w\n",Directory,End);
+
+ IData = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(KERNEL32_FIND_FILE_DATA));
+
+ RtlInitUnicodeString(&DirectoryNameStr, Directory);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirectoryNameStr,
+ 0,
+ NULL,
+ NULL);
+
+ if (ZwOpenFile(&IData->DirectoryHandle,
+ FILE_TRAVERSE,
+ &ObjectAttributes,
+ 0,
+ OPEN_EXISTING)!=STATUS_SUCCESS)
+ {
+ return(NULL);
+ }
+
+ NtQueryDirectoryFile(IData->DirectoryHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ &IData->FileInfo,
+ sizeof(IData->FileInfo),
+ FileDirectoryInformation,
+ TRUE,
+ Pattern,
+ FALSE);
+
+ return(IData);
+}
+
+WINBOOL STDCALL FindNextFileW(HANDLE hFindFile,
+ LPWIN32_FIND_DATA lpFindFileData)
+{
+}
kernel32.a: $(OBJECTS)
- $(AR) vrcs kernel32.a $(OBJECTS)
+ $(AR) rcs kernel32.a $(OBJECTS)
dummy:
* Put the type definitions of the heap in a seperate header. Boudewijn Dekker
*/
-#include <kernel32/proc.h>
+#define NDEBUG
#include <kernel32/kernel32.h>
+
+#include <kernel32/proc.h>
#include <kernel32/heap.h>
#include <internal/string.h>
*********************************************************************/
static BOOL __HeapCommit(PHEAP pheap, LPVOID start, LPVOID end)
{
- dprintf("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
+ DPRINT("__HeapCommit( 0x%lX, 0x%lX, 0x%lX)\n",
(ULONG) pheap, (ULONG) start, (ULONG) end);
if(end >= pheap->LastBlock)
*********************************************************************/
static BOOL __HeapDecommit(PHEAP pheap, LPVOID start, LPVOID end)
{
- dprintf("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
+ DPRINT("__HeapDecommit( 0x%lX, 0x%lX, 0x%lX)\n",
(ULONG) pheap, (ULONG) start, (ULONG) end);
#ifdef NOT
__VirtualDump();
ULONG freesize;
ULONG allocsize;
- dprintf("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
+ DPRINT("__HeapAlloc(pheap %x, flags %x, size %d, tag %x)\n",
pheap,flags,size,tag);
pfree=&(pheap->Start);
*/
if(size==0)
{
- dprintf("__HeapReAlloc: freeing memory\n");
+ DPRINT("__HeapReAlloc: freeing memory\n");
__HeapFree(pheap, flags, pold);
return NULL;
}
#endif
else if(newsize < allocsize )
{
- dprintf("__HeapReAlloc: shrinking memory\n");
+ DPRINT("__HeapReAlloc: shrinking memory\n");
/* free remaining region of memory */
prealloc->Size=size | HEAP_NORMAL_TAG;
pnext=HEAP_NEXT(prealloc);
}
else if(newsize == allocsize )
{
- dprintf("__HeapReAlloc: no changes\n");
+ DPRINT("__HeapReAlloc: no changes\n");
/* nothing to do */
prealloc->Size= size | HEAP_NORMAL_TAG;
return pold;
if(((LPVOID) pnext< pheap->End)&& HEAP_ISFREE(pnext) &&
(HEAP_SIZE(pnext) + HEAP_ADMIN_SIZE >=newsize-allocsize))
{
- dprintf("__HeapReAlloc: joining memory\n");
+ DPRINT("__HeapReAlloc: joining memory\n");
oldsize=HEAP_SIZE(prealloc);
prealloc->Size=size | HEAP_NORMAL_TAG;
{
if((flags&HEAP_REALLOC_IN_PLACE_ONLY)==0)
{
- dprintf("__HeapReAlloc: allocating new memory\n");
+ DPRINT("__HeapReAlloc: allocating new memory\n");
/* alloc a new piece of memory */
oldsize=HEAP_SIZE(prealloc);
pmem=__HeapAlloc(pheap, flags, size, HEAP_NORMAL_TAG);
{
PHEAP pheap=(PHEAP) base;
- dprintf("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
+ DPRINT("__HeapPrepare(base %x, minsize %d, maxsize %d, flags %x)\n",
base,minsize,maxsize,flags);
pheap->Magic=MAGIC_HEAP;
{
PHEAP pheap;
- aprintf("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, minsize, maxsize);
+ DPRINT("HeapCreate( 0x%lX, 0x%lX, 0x%lX )\n", flags, minsize, maxsize);
pheap = VirtualAlloc(NULL, minsize, MEM_TOP_DOWN, PAGE_READWRITE);
VirtualAlloc(pheap, PAGESIZE, MEM_COMMIT, PAGE_READWRITE);
{
PHEAP pheap=(PHEAP) hheap;
- aprintf("HeapDestroy( 0x%lX )\n", (ULONG) hheap );
+ DPRINT("HeapDestroy( 0x%lX )\n", (ULONG) hheap );
if(pheap->Magic!=MAGIC_HEAP)
return __ErrorReturnFalse(ERROR_INVALID_PARAMETER);
PHEAP pheap=hheap;
LPVOID retval;
- aprintf("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
+ DPRINT("HeapAlloc( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
if( (flags | pheap->Flags) & HEAP_NO_SERIALIZE )
LeaveCriticalSection(&(pheap->Synchronize));
- aprintf("HeapAlloc returns 0x%lX\n", (ULONG) retval);
+ DPRINT("HeapAlloc returns 0x%lX\n", (ULONG) retval);
return retval;
PHEAP_BLOCK pfree=((PHEAP_BLOCK)ptr-1);
LPVOID retval;
- aprintf("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
+ DPRINT("HeapReAlloc( 0x%lX, 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) ptr, size );
#ifdef NOT
HeapValidate(hheap, 0, 0);
PHEAP_BLOCK pfree=(PHEAP_BLOCK)((DWORD)ptr-HEAP_ADMIN_SIZE);
BOOL retval;
- aprintf("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
- (ULONG) hheap, flags, (ULONG) ptr );
+ DPRINT("HeapFree( 0x%lX, 0x%lX, 0x%lX )\n",
+ (ULONG) hheap, flags, (ULONG) ptr );
#ifdef NOT
HeapValidate(hheap, 0, 0);
#endif
*********************************************************************/
HANDLE WINAPI GetProcessHeap(VOID)
{
- aprintf("GetProcessHeap()\n");
+ DPRINT("GetProcessHeap()\n");
return (HANDLE) __ProcessHeap;
}
DWORD retval;
PHEAP pheap;
- aprintf("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
+ DPRINT("GetProcessHeaps( %u, 0x%lX )\n", maxheaps, (ULONG) phandles );
pheap= __ProcessHeap;
retval=0;
{
PHEAP pheap=hheap;
- aprintf("HeapLock( 0x%lX )\n", (ULONG) hheap );
+ DPRINT("HeapLock( 0x%lX )\n", (ULONG) hheap );
EnterCriticalSection(&(pheap->Synchronize));
return TRUE;
{
PHEAP pheap=hheap;
- aprintf("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
+ DPRINT("HeapUnlock( 0x%lX )\n", (ULONG) hheap );
LeaveCriticalSection(&(pheap->Synchronize));
return TRUE;
PHEAP_BLOCK palloc=((PHEAP_BLOCK)pmem-1);
DWORD retval=0;
- aprintf("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
+ DPRINT("HeapSize( 0x%lX, 0x%lX, 0x%lX )\n",
(ULONG) hheap, flags, (ULONG) pmem );
if(pheap->Magic!=MAGIC_HEAP)
pnext=HEAP_NEXT(pcheck);
if((pprev)&&(HEAP_PREV(pcheck)!=pprev))
{
- dprintf("HeapValidate: linked list invalid, region 0x%lX,"
+ DPRINT("HeapValidate: linked list invalid, region 0x%lX,"
" previous region 0x%lX, list says 0x%lX\n",
(ULONG)pcheck, (ULONG)pprev, (ULONG) HEAP_PREV(pcheck));
return FALSE;
{
DWORD i;
- dprintf("CopyMemory(Destination %x, Source %x, Length %d)\n",
- Destination,Source,Length);
-
for (i=0; i<Length; i++)
{
((PCH)Destination)[i] = ((PCH)Source)[i];
* UPDATE HISTORY:
* Created 01/11/98
*/
+
+/* INCLUDES ****************************************************************/
+
#define UNICODE
#include <windows.h>
#include <kernel32/proc.h>
#include <ddk/rtl.h>
#include <ddk/li.h>
-NT_PEB CurrentPeb;
+#define NDEBUG
+#include <kernel32/kernel32.h>
+/* GLOBALS *****************************************************************/
+static NT_PEB *CurrentPeb;
+static NT_PEB Peb;
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
-wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs );
-
-WINBOOL
-STDCALL
-GetProcessId(HANDLE hProcess, LPDWORD lpProcessId );
-
-
+/* FUNCTIONS ****************************************************************/
+WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
NT_PEB *GetCurrentPeb(VOID)
{
- return &CurrentPeb;
-
+ if ( CurrentPeb != NULL )
+ return CurrentPeb;
+ else // hack to be able to return a process environment any time.
+ return &Peb;
}
HANDLE STDCALL GetCurrentProcess(VOID)
return (HANDLE)NtCurrentThread();
}
-DWORD
-STDCALL
-GetCurrentProcessId(VOID)
-{
-
- return (DWORD)(GetTeb()->Cid).UniqueProcess;
-
-
+DWORD STDCALL GetCurrentProcessId(VOID)
+{
+ return (DWORD)(GetTeb()->Cid).UniqueProcess;
}
-unsigned char CommandLineA[MAX_PATH];
-
-LPSTR
-STDCALL
-GetCommandLineA(
- VOID
- )
-{
- WCHAR *CommandLineW;
- ULONG i = 0;
-
- CommandLineW = GetCommandLineW();
- while ((CommandLineW[i])!=0 && i < MAX_PATH)
- {
- CommandLineA[i] = (unsigned char)CommandLineW[i];
- i++;
- }
- CommandLineA[i] = 0;
- return CommandLineA;
-}
-LPWSTR
-STDCALL
-GetCommandLineW(
- VOID
- )
+WINBOOL STDCALL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode )
{
- return GetCurrentPeb()->StartupInfo->CommandLine;
+ NTSTATUS errCode;
+ PROCESS_BASIC_INFORMATION ProcessBasic;
+ ULONG BytesWritten;
+
+ errCode = NtQueryInformationProcess(hProcess,
+ ProcessBasicInformation,
+ &ProcessBasic,
+ sizeof(PROCESS_BASIC_INFORMATION),
+ &BytesWritten);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
+ return TRUE;
}
-wchar_t **CommandLineToArgvW(LPCWSTR lpCmdLine, int * pNumArgs )
+WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId )
{
- return NULL;
-}
-
-
-
-WINBOOL
-STDCALL
-GetExitCodeProcess(
- HANDLE hProcess,
- LPDWORD lpExitCode
- )
-{
- NTSTATUS errCode;
- PROCESS_BASIC_INFORMATION ProcessBasic;
- ULONG BytesWritten;
-
- errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
- memcpy( lpExitCode ,&ProcessBasic.ExitStatus,sizeof(DWORD));
- return TRUE;
-
+ NTSTATUS errCode;
+ PROCESS_BASIC_INFORMATION ProcessBasic;
+ ULONG BytesWritten;
+
+ errCode = NtQueryInformationProcess(hProcess,
+ ProcessBasicInformation,
+ &ProcessBasic,
+ sizeof(PROCESS_BASIC_INFORMATION),
+ &BytesWritten);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+ memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
+ return TRUE;
}
-WINBOOL
-STDCALL
-GetProcessId(
- HANDLE hProcess,
- LPDWORD lpProcessId
- )
+PWSTR InternalAnsiToUnicode(PWSTR Out, LPCSTR In, ULONG MaxLength)
{
- NTSTATUS errCode;
- PROCESS_BASIC_INFORMATION ProcessBasic;
- ULONG BytesWritten;
-
- errCode = NtQueryInformationProcess(hProcess,ProcessBasicInformation,&ProcessBasic,sizeof(PROCESS_BASIC_INFORMATION),&BytesWritten);
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
- memcpy( lpProcessId ,&ProcessBasic.UniqueProcessId,sizeof(DWORD));
- return TRUE;
-
+ ULONG i;
+
+ if (In == NULL)
+ {
+ return(NULL);
+ }
+ else
+ {
+ i = 0;
+ while ((*In)!=0 && i < MaxLength)
+ {
+ Out[i] = *In;
+ In++;
+ i++;
+ }
+ Out[i] = 0;
+ return(Out);
+ }
}
-WINBOOL
-STDCALL
-CreateProcessA(
- LPCSTR lpApplicationName,
- LPSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- WINBOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCSTR lpCurrentDirectory,
- LPSTARTUPINFO lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation
- )
+WINBOOL STDCALL CreateProcessA(LPCSTR lpApplicationName,
+ LPSTR lpCommandLine,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ WINBOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ LPVOID lpEnvironment,
+ LPCSTR lpCurrentDirectory,
+ LPSTARTUPINFO lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation)
+/*
+ * FUNCTION: The CreateProcess function creates a new process and its
+ * primary thread. The new process executes the specified executable file
+ * ARGUMENTS:
+ *
+ * lpApplicationName = Pointer to name of executable module
+ * lpCommandLine = Pointer to command line string
+ * lpProcessAttributes = Process security attributes
+ * lpThreadAttributes = Thread security attributes
+ * bInheritHandles = Handle inheritance flag
+ * dwCreationFlags = Creation flags
+ * lpEnvironment = Pointer to new environment block
+ * lpCurrentDirectory = Pointer to current directory name
+ * lpStartupInfo = Pointer to startup info
+ * lpProcessInformation = Pointer to process information
+ */
{
- WCHAR ApplicationNameW[MAX_PATH];
- WCHAR CommandLineW[MAX_PATH];
- WCHAR CurrentDirectoryW[MAX_PATH];
-
-
- ULONG i;
-
- i = 0;
- while ((*lpApplicationName)!=0 && i < MAX_PATH)
- {
- ApplicationNameW[i] = *lpApplicationName;
- lpApplicationName++;
- i++;
- }
- ApplicationNameW[i] = 0;
-
-
- i = 0;
- while ((*lpCommandLine)!=0 && i < MAX_PATH)
- {
- CommandLineW[i] = *lpCommandLine;
- lpCommandLine++;
- i++;
- }
- CommandLineW[i] = 0;
-
- i = 0;
- while ((*lpCurrentDirectory)!=0 && i < MAX_PATH)
- {
- CurrentDirectoryW[i] = *lpCurrentDirectory;
- lpCurrentDirectory++;
- i++;
- }
- CurrentDirectoryW[i] = 0;
-
- return CreateProcessW(ApplicationNameW,CommandLineW, lpProcessAttributes,lpThreadAttributes,
- bInheritHandles,dwCreationFlags,lpEnvironment,CurrentDirectoryW,lpStartupInfo,
- lpProcessInformation);
-
-
+ WCHAR ApplicationNameW[MAX_PATH];
+ WCHAR CommandLineW[MAX_PATH];
+ WCHAR CurrentDirectoryW[MAX_PATH];
+ PWSTR PApplicationNameW;
+ PWSTR PCommandLineW;
+ PWSTR PCurrentDirectoryW;
+ ULONG i;
+
+ DPRINT("CreateProcessA\n");
+
+ PApplicationNameW = InternalAnsiToUnicode(ApplicationNameW,
+ lpApplicationName,
+ MAX_PATH);
+ PCommandLineW = InternalAnsiToUnicode(CommandLineW,
+ lpCommandLine,
+ MAX_PATH);
+ PCurrentDirectoryW = InternalAnsiToUnicode(CurrentDirectoryW,
+ lpCurrentDirectory,
+ MAX_PATH);
+ return CreateProcessW(PApplicationNameW,
+ PCommandLineW,
+ lpProcessAttributes,
+ lpThreadAttributes,
+ bInheritHandles,
+ dwCreationFlags,
+ lpEnvironment,
+ PCurrentDirectoryW,
+ lpStartupInfo,
+ lpProcessInformation);
}
-WINBOOL
-STDCALL
-CreateProcessW(
- LPCWSTR lpApplicationName,
- LPWSTR lpCommandLine,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- WINBOOL bInheritHandles,
- DWORD dwCreationFlags,
- LPVOID lpEnvironment,
- LPCWSTR lpCurrentDirectory,
- LPSTARTUPINFO lpStartupInfo,
- LPPROCESS_INFORMATION lpProcessInformation
- )
+WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
+ LPWSTR lpCommandLine,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ WINBOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ LPVOID lpEnvironment,
+ LPCWSTR lpCurrentDirectory,
+ LPSTARTUPINFO lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation)
{
- HANDLE hFile, hSection, hProcess, hThread;
- KPRIORITY PriorityClass;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- BOOLEAN CreateSuspended;
-
- NTSTATUS errCode;
-
- UNICODE_STRING ApplicationNameString;
-
-
-
- LPTHREAD_START_ROUTINE lpStartAddress = NULL;
- LPVOID lpParameter = NULL;
-
- hFile = NULL;
-
- ApplicationNameString.Length = lstrlenW(lpApplicationName)*sizeof(WCHAR);
+ HANDLE hFile, hSection, hProcess, hThread;
+ KPRIORITY PriorityClass;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ BOOLEAN CreateSuspended;
+ NTSTATUS errCode;
+ UNICODE_STRING ApplicationNameString;
+ LPTHREAD_START_ROUTINE lpStartAddress = NULL;
+ LPVOID lpParameter = NULL;
+ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+ WCHAR TempApplicationName[255];
+ WCHAR TempFileName[255];
+ WCHAR TempDirectoryName[255];
+ ULONG i;
+ ULONG BaseAddress;
+ ULONG Size;
+ LARGE_INTEGER SectionOffset;
- ApplicationNameString.Buffer = (WCHAR *)lpApplicationName;
- ApplicationNameString.MaximumLength = ApplicationNameString.Length+sizeof(WCHAR);
-
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
-
-
-
- if ( lpProcessAttributes != NULL ) {
- if ( lpProcessAttributes->bInheritHandle )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- else
- ObjectAttributes.Attributes = 0;
- ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
- }
- ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
-
- errCode = NtOpenFile(&hFile,(SYNCHRONIZE|FILE_EXECUTE), &ObjectAttributes,
- &IoStatusBlock,(FILE_SHARE_DELETE|FILE_SHARE_READ),(FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE));
-
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
- errCode = NtCreateSection(&hSection,SECTION_ALL_ACCESS,NULL,NULL,PAGE_EXECUTE,SEC_IMAGE,hFile);
- NtClose(hFile);
-
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
-
- if ( lpProcessAttributes != NULL ) {
- if ( lpProcessAttributes->bInheritHandle )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- else
- ObjectAttributes.Attributes = 0;
- ObjectAttributes.SecurityDescriptor = lpProcessAttributes->lpSecurityDescriptor;
- }
-
- errCode = NtCreateProcess(&hProcess,PROCESS_ALL_ACCESS, &ObjectAttributes,NtCurrentProcess(),bInheritHandles,hSection,NULL,NULL);
- NtClose(hSection);
-
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return FALSE;
- }
-
- PriorityClass = NORMAL_PRIORITY_CLASS;
- NtSetInformationProcess(hProcess,ProcessBasePriority,&PriorityClass,sizeof(KPRIORITY));
-
- if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED)
- CreateSuspended = TRUE;
- else
- CreateSuspended = FALSE;
-
- hThread = CreateRemoteThread(
- hProcess,
- lpThreadAttributes,
- 4096, // 1 page ??
- lpStartAddress,
- lpParameter,
- CREATE_SUSPENDED,
- &lpProcessInformation->dwThreadId
- );
-
-
- if ( hThread == NULL )
- return FALSE;
-
-
-
- lpProcessInformation->hProcess = hProcess;
- lpProcessInformation->hThread = hThread;
-
-
-
-
- GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
+ DPRINT("CreateProcessW(lpApplicationName '%w', lpCommandLine '%w')\n",
+ lpApplicationName,lpCommandLine);
+
+ hFile = NULL;
+
+ /*
+ * Find the application name
+ */
+ TempApplicationName[0] = '\\';
+ TempApplicationName[1] = '?';
+ TempApplicationName[2] = '?';
+ TempApplicationName[3] = '\\';
+ TempApplicationName[4] = 0;
+
+ DPRINT("TempApplicationName '%w'\n",TempApplicationName);
+
+ if (lpApplicationName != NULL)
+ {
+ wcscpy(TempFileName, lpApplicationName);
+
+ DPRINT("TempFileName '%w'\n",TempFileName);
+ }
+ else
+ {
+ wcscpy(TempFileName, lpCommandLine);
+
+ DPRINT("TempFileName '%w'\n",TempFileName);
+
+ for (i=0; TempFileName[i]!=' ' && TempFileName[i] != 0; i++);
+ TempFileName[i]=0;
+
+ }
+ if (TempFileName[1] != ':')
+ {
+ GetCurrentDirectoryW(MAX_PATH,TempDirectoryName);
+ wcscat(TempApplicationName,TempDirectoryName);
+ }
+ wcscat(TempApplicationName,TempFileName);
+
+ RtlInitUnicodeString(&ApplicationNameString, TempApplicationName);
+
+ DPRINT("ApplicationName %w\n",ApplicationNameString.Buffer);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ApplicationNameString,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ SecurityDescriptor);
+
+ /*
+ * Try to open the executable
+ */
+
+ errCode = NtOpenFile(&hFile,
+ SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_DELETE|FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
+
+ if ( !NT_SUCCESS(errCode) )
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+ errCode = NtCreateSection(&hSection,
+ SECTION_ALL_ACCESS,
+ NULL,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_IMAGE,
+ hFile);
+ NtClose(hFile);
+
+ if ( !NT_SUCCESS(errCode) )
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+ errCode = NtCreateProcess(&hProcess,
+ PROCESS_ALL_ACCESS,
+ NULL,
+ NtCurrentProcess(),
+ bInheritHandles,
+ NULL,
+ NULL,
+ NULL);
+
+ BaseAddress = (PVOID)0x10000;
+ LARGE_INTEGER_QUAD_PART(SectionOffset) = 0;
+ Size = 0x10000;
+ NtMapViewOfSection(hSection,
+ hProcess,
+ &BaseAddress,
+ 0,
+ Size,
+ &SectionOffset,
+ &Size,
+ 0,
+ MEM_COMMIT,
+ PAGE_READWRITE);
-
+
+ NtClose(hSection);
- return TRUE;
-
-
- }
+ if ( !NT_SUCCESS(errCode) )
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return FALSE;
+ }
+
+#if 0
+ PriorityClass = NORMAL_PRIORITY_CLASS;
+ NtSetInformationProcess(hProcess,
+ ProcessBasePriority,
+ &PriorityClass,
+ sizeof(KPRIORITY));
+#endif
+ DPRINT("Creating thread for process\n");
+ lpStartAddress = BaseAddress;
+ hThread = CreateRemoteThread(hProcess,
+ lpThreadAttributes,
+ 4096, // 1 page ??
+ lpStartAddress,
+ lpParameter,
+ dwCreationFlags,
+ &lpProcessInformation->dwThreadId);
+
+ if ( hThread == NULL )
+ return FALSE;
+
+ lpProcessInformation->hProcess = hProcess;
+ lpProcessInformation->hThread = hThread;
+
+ GetProcessId(hProcess,&lpProcessInformation->dwProcessId);
+
+ return TRUE;
+}
-HANDLE
-STDCALL
-OpenProcess(
- DWORD dwDesiredAccess,
- WINBOOL bInheritHandle,
- DWORD dwProcessId
- )
+HANDLE STDCALL OpenProcess(DWORD dwDesiredAccess,
+ WINBOOL bInheritHandle,
+ DWORD dwProcessId)
{
-
-
- NTSTATUS errCode;
- HANDLE ProcessHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId ;
-
- ClientId.UniqueProcess = (HANDLE)dwProcessId;
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = (HANDLE)NULL;
- ObjectAttributes.SecurityDescriptor = NULL;
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- if ( bInheritHandle == TRUE )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- else
- ObjectAttributes.Attributes = 0;
-
- errCode = NtOpenProcess ( &ProcessHandle, dwDesiredAccess, &ObjectAttributes, &ClientId);
- if ( !NT_SUCCESS(errCode) ) {
- SetLastError(RtlNtStatusToDosError(errCode));
- return NULL;
- }
- return ProcessHandle;
+ NTSTATUS errCode;
+ HANDLE ProcessHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ CLIENT_ID ClientId ;
+
+ ClientId.UniqueProcess = (HANDLE)dwProcessId;
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = (HANDLE)NULL;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+ if ( bInheritHandle == TRUE )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ else
+ ObjectAttributes.Attributes = 0;
+
+ errCode = NtOpenProcess(&ProcessHandle,
+ dwDesiredAccess,
+ &ObjectAttributes,
+ &ClientId);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastError(RtlNtStatusToDosError(errCode));
+ return NULL;
+ }
+ return ProcessHandle;
}
-UINT WinExec ( LPCSTR lpCmdLine, UINT uCmdShow )
+UINT WinExec (LPCSTR lpCmdLine, UINT uCmdShow)
{
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
-
- HINSTANCE hInst;
- DWORD dosErr;
-
-
-
- StartupInfo.cb = sizeof(STARTUPINFO);
- StartupInfo.wShowWindow = uCmdShow ;
- StartupInfo.dwFlags = 0;
-
- hInst = (HINSTANCE)CreateProcessA(NULL,(PVOID)lpCmdLine,NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo, &ProcessInformation);
- if ( hInst == NULL ) {
- dosErr = GetLastError();
- return dosErr;
- }
- if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
- lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
- NtClose(ProcessInformation.hProcess);
- NtClose(ProcessInformation.hThread);
- return 0;
-
+ STARTUPINFO StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
+ HINSTANCE hInst;
+ DWORD dosErr;
+
+ StartupInfo.cb = sizeof(STARTUPINFO);
+ StartupInfo.wShowWindow = uCmdShow ;
+ StartupInfo.dwFlags = 0;
+
+ hInst = (HINSTANCE)CreateProcessA(NULL,
+ (PVOID)lpCmdLine,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation);
+ if ( hInst == NULL )
+ {
+ dosErr = GetLastError();
+ return dosErr;
+ }
+ if ( lpfnGlobalRegisterWaitForInputIdle != NULL )
+ lpfnGlobalRegisterWaitForInputIdle(ProcessInformation.hProcess,10000);
+ NtClose(ProcessInformation.hProcess);
+ NtClose(ProcessInformation.hThread);
+ return 0;
}
+
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
{
lpfnGlobalRegisterWaitForInputIdle = lpfnRegisterWaitForInputIdle;
return;
}
-DWORD
-STDCALL
-WaitForInputIdle(
- HANDLE hProcess,
- DWORD dwMilliseconds
- )
+DWORD STDCALL WaitForInputIdle(HANDLE hProcess,
+ DWORD dwMilliseconds)
{
- return 0;
+ return 0;
}
VOID
BOOL bAlertable
)
{
- LARGE_INTEGER Interval;
+ TIME Interval;
NTSTATUS errCode;
- SET_LARGE_INTEGER_LOW_PART(Interval,dwMilliseconds*1000);
+ Interval.LowPart = dwMilliseconds * 1000;
+ Interval.HighPart = 0;
errCode = NtDelayExecution(bAlertable,&Interval);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
- lstrcpyW(lpStartupInfo->lpDesktop,(WCHAR *) pPeb->StartupInfo->Desktop);
- lstrcpyW(lpStartupInfo->lpTitle, (WCHAR *)pPeb->StartupInfo->Title);
+ lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
+ lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
{
- lpStartupInfo->lpDesktop[i] = (char)pPeb->StartupInfo->Desktop[i];
+ lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
i++;
}
lpStartupInfo->lpDesktop[i] = 0;
i = 0;
while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
{
- lpStartupInfo->lpTitle[i] = (char)pPeb->StartupInfo->Title[i];
+ lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
i++;
}
lpStartupInfo->lpTitle[i] = 0;
return TRUE;
}
-VOID
-STDCALL
-ExitProcess(
- UINT uExitCode
- )
-{
-
- NtTerminateProcess(
- NtCurrentProcess() ,
- uExitCode
- );
-
+VOID STDCALL ExitProcess(UINT uExitCode)
+{
+ NtTerminateProcess(NtCurrentProcess() ,uExitCode);
}
VOID
-VOID
-STDCALL
-FatalAppExitW(
- UINT uAction,
- LPCWSTR lpMessageText
- )
+VOID STDCALL FatalAppExitW(UINT uAction, LPCWSTR lpMessageText)
{
- return;
+ return;
}
-HMODULE
-STDCALL
-GetModuleHandleA(
- LPCSTR lpModuleName
- )
-{
- if ( lpModuleName == NULL )
- return 0x00010000; // starting address of current module
- else
- return NULL; // should return the address of the specified module
-
- return NULL;
-
-}
-
-HMODULE
-STDCALL
-GetModuleHandleW(
- LPCWSTR lpModuleName
- )
-{
- if ( lpModuleName == NULL )
- return 0x00010000; // starting address of current module
- else
- return NULL; // should return the address of the specified module
-
- return NULL;
-}
-
-
#include <kernel32/thread.h>
#include <ddk/ntddk.h>
#include <string.h>
-
+#include <internal/i386/segment.h>
HANDLE
STDCALL
LPDWORD lpThreadId
)
{
- NTSTATUS errCode;
- HANDLE ThreadHandle;
- OBJECT_ATTRIBUTES ObjectAttributes;
- CLIENT_ID ClientId;
- CONTEXT ThreadContext;
- INITIAL_TEB InitialTeb;
- BOOLEAN CreateSuspended = FALSE;
-
- ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
- ObjectAttributes.RootDirectory = NULL;
- ObjectAttributes.ObjectName = NULL;
- ObjectAttributes.Attributes = 0;
- if ( lpThreadAttributes != NULL ) {
- if ( lpThreadAttributes->bInheritHandle )
- ObjectAttributes.Attributes = OBJ_INHERIT;
- ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
- }
- ObjectAttributes.SecurityQualityOfService = NULL;
-
- if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
+ NTSTATUS errCode;
+ HANDLE ThreadHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ CLIENT_ID ClientId;
+ CONTEXT ThreadContext;
+ INITIAL_TEB InitialTeb;
+ BOOLEAN CreateSuspended = FALSE;
+ ULONG BaseAddress;
+
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = NULL;
+ ObjectAttributes.Attributes = 0;
+ if ( lpThreadAttributes != NULL ) {
+ if ( lpThreadAttributes->bInheritHandle )
+ ObjectAttributes.Attributes = OBJ_INHERIT;
+ ObjectAttributes.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
+ }
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
+ if ( ( dwCreationFlags & CREATE_SUSPENDED ) == CREATE_SUSPENDED )
CreateSuspended = TRUE;
- else
- CreateSuspended = FALSE;
- // fix context
- GetThreadContext(NtCurrentThread(),&ThreadContext);
- // fix teb [ stack context ] --> check the image file
-
- errCode = NtCreateThread(
- &ThreadHandle,
- THREAD_ALL_ACCESS,
- &ObjectAttributes,
- hProcess,
- &ClientId,
- &ThreadContext,
- &InitialTeb,
- CreateSuspended
- );
- if ( lpThreadId != NULL )
- memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
-
- return ThreadHandle;
+ else
+ CreateSuspended = FALSE;
+
+ BaseAddress = 0;
+ ZwAllocateVirtualMemory(hProcess,
+ &BaseAddress,
+ 0,
+ &dwStackSize,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+
+ memset(&ThreadContext,0,sizeof(CONTEXT));
+ ThreadContext.Eip = lpStartAddress;
+ ThreadContext.SegGs = USER_DS;
+ ThreadContext.SegFs = USER_DS;
+ ThreadContext.SegEs = USER_DS;
+ ThreadContext.SegDs = USER_DS;
+ ThreadContext.SegCs = USER_CS;
+ ThreadContext.SegSs = USER_DS;
+ ThreadContext.Esp = BaseAddress + dwStackSize;
+ ThreadContext.EFlags = (1<<1) + (1<<9);
+
+
+ errCode = NtCreateThread(&ThreadHandle,
+ THREAD_ALL_ACCESS,
+ &ObjectAttributes,
+ hProcess,
+ &ClientId,
+ &ThreadContext,
+ &InitialTeb,
+ CreateSuspended);
+ if ( lpThreadId != NULL )
+ memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
+
+ return ThreadHandle;
}
NT_TEB *GetTeb(VOID)
return NULL;
}
-WINBOOL STDCALL
-SwitchToThread(VOID )
+WINBOOL STDCALL SwitchToThread(VOID )
{
NTSTATUS errCode;
errCode = NtYieldExecution();
return TRUE;
}
-DWORD
-STDCALL
-GetCurrentThreadId()
+DWORD STDCALL GetCurrentThreadId()
{
return (DWORD)(GetTeb()->Cid).UniqueThread;
}
-VOID
-STDCALL
-ExitThread(
- UINT uExitCode
- )
+VOID STDCALL ExitThread(UINT uExitCode)
{
NTSTATUS errCode;
/* TYPES *********************************************************************/
+#define CACHE_SEGMENT_INVALID (0) // Isn't valid
+#define CACHE_SEGMENT_WRITTEN (1) // Written
+#define CACHE_SEGMENT_READ (2)
+
typedef struct _CACHE_SEGMENT
{
- ULONG Type;
+ ULONG Type; // Debugging
ULONG Size;
- LIST_ENTRY ListEntry;
- PVOID BaseAddress;
- ULONG Length;
- ULONG State;
- MEMORY_AREA* MemoryArea;
- ULONG FileOffset;
- ULONG InternalOffset;
+ LIST_ENTRY ListEntry; // Entry in the per-open list of segments
+ PVOID BaseAddress; // Base address of the mapping
+ ULONG Length; // Length of the mapping
+ ULONG State; // Information
+ MEMORY_AREA* MemoryArea; // Memory area for the mapping
+ ULONG FileOffset; // Offset within the file of the mapping
+ KEVENT Event;
+ BOOLEAN Dirty; // Contains dirty data
} CACHE_SEGMENT, *PCACHE_SEGMENT;
typedef struct _CC1_CCB
ULONG Type;
ULONG Size;
LIST_ENTRY CacheSegmentListHead;
+ KSPIN_LOCK CacheSegmentListLock;
LIST_ENTRY ListEntry;
} CC1_CCB, PCC1_CCB;
/* FUNCTIONS *****************************************************************/
-PVOID Cc1FlushView(PFILE_OBJECT FileObject,
+PVOID Cc1FlushView(PCC1_CCB CacheDesc,
ULONG FileOffset,
ULONG Length)
{
}
-PVOID Cc1PurgeView(PFILE_OBJECT FileObject,
+PVOID Cc1PurgeView(PCC1_CCB CacheDesc,
ULONG FileOffset,
ULONG Length)
{
}
-VOID Cc1ViewIsUpdated(PFILE_OBJECT FileObject,
- ULONG FileOffset)
+BOOLEAN Cc1AcquireCacheSegment(PCACHE_SEGMENT CacheSegment,
+ BOOLEAN AcquireForWrite,
+ BOOLEAN Wait)
{
+
}
-
-typedef
-
-BOOLEAN Cc1RequestView(PFILE_OBJECT FileObject,
- ULONG FileOffset,
- ULONG Length,
- BOOLEAN Wait,
- BOOLEAN AcquireForWrite)
+
+PVOID Cc1RequestView(PCC1_CCB CacheDesc,
+ ULONG FileOffset,
+ ULONG Length,
+ BOOLEAN Wait,
+ BOOLEAN AcquireForWrite)
/*
* FUNCTION: Request a view for caching data
* ARGUMENTS:
* False otherwise
*/
{
+ PLIST_ENTRY current_entry;
+ PCACHE_SEGMENT current;
+
+ KeAcquireSpinLock(&CacheDesc->CacheSegmentListLock);
+
+ current_entry = CacheDesc->CacheSegmentListHead.Flink;
+ while (current_entry != &CacheDesc->CacheSegmentListHead)
+ {
+ current = CONTAING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
+
+ if (current->FileOffset <= FileOffset &&
+ (current->FileOffset + current->length) >= (FileOffset + Length))
+ {
+ if (!Cc1AcquireCacheSegment(AcquireForWrite, Wait))
+ {
+ return(NULL);
+ }
+ return(current->BaseAddress + (FileOffset - current->FileOffset));
+ }
+ current_entry = current_entry->Flink;
+ }
+
+ KeReleaseSpinLock(&CacheDesc->CacheSegmentListLock);
}
-BOOLEAN Cc1InitializeFileCache(PFILE_OBJECT FileObject)
+PCC1_CCB Cc1InitializeFileCache(PFILE_OBJECT FileObject)
/*
* FUNCTION: Initialize caching for a file
*/
{
+ PCC1_CCB CacheDesc;
+
+ CacheDesc = ExAllocatePool(NonPagedPool, sizeof(CC1_CCB));
+ InitializeListHead(&CacheDesc->CacheSegmentListHead);
+ KeAcquireSpinLock(&CacheDesc->CacheSegmentListLock);
+
+ return(CacheDesc);
}
Stack = (PVOID)(((ULONG)Stack) & (~0x3));
DbgPrint("Frames:\n");
- for (i=0; i<1024; i++)
+ for (i=0; i<32; i++)
{
if (Stack[i] > KERNEL_BASE && Stack[i] < ((ULONG)&etext))
{
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/hal/x86/thread.c\r
- * PURPOSE: HAL multitasking functions\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * REVISION HISTORY:\r
- * 27/06/98: Created\r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <windows.h>\r
-#include <ddk/ntddk.h>\r
-#include <internal/ntoskrnl.h>\r
-#include <internal/ps.h>\r
-#include <internal/string.h>\r
-#include <internal/hal.h>\r
-#include <internal/i386/segment.h>\r
-#include <internal/mmhal.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* GLOBALS ***************************************************************/\r
-\r
-VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);\r
-VOID PsBeginThreadWithContextInternal(VOID);\r
-\r
-#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)\r
-#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)\r
-\r
-static char null_ldt[8]={0,};\r
-static unsigned int null_ldt_sel=0;\r
-static PETHREAD FirstThread=NULL;\r
-\r
-/* FUNCTIONS **************************************************************/\r
-\r
-void HalTaskSwitch(PKTHREAD thread)\r
-/*\r
- * FUNCTION: Switch tasks\r
- * ARGUMENTS:\r
- * thread = Thread to switch to\r
- * NOTE: This function will not return until the current thread is scheduled\r
- * again\r
- */\r
-{\r
- DPRINT("Scheduling thread %x\n",thread);\r
- DPRINT("Scheduling thread %x\n",thread->Context.nr);\r
- DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",\r
- thread->Context.previous_task,thread->Context.reserved1,\r
- thread->Context.esp0,thread->Context.ss0);\r
- DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",\r
- thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,\r
- thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);\r
- DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",\r
- thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,\r
- thread->Context.eflags,thread->Context.eax);\r
- DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",\r
- thread->Context.ecx,thread->Context.edx,thread->Context.ebx,\r
- thread->Context.esp,thread->Context.ebp,thread->Context.esi);\r
- DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",\r
- thread->Context.edi,thread->Context.es,thread->Context.reserved5,\r
- thread->Context.cs,thread->Context.reserved6);\r
- DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",\r
- thread->Context.ss,thread->Context.reserved7,thread->Context.ds,\r
- thread->Context.reserved8,thread->Context.fs);\r
- DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",\r
- thread->Context.reserved9,thread->Context.gs,\r
- thread->Context.reserved10,thread->Context.ldt,\r
- thread->Context.reserved11);\r
- DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",\r
- thread->Context.trap,thread->Context.iomap_base,\r
- thread->Context.nr,thread->Context.io_bitmap[0]);\r
- DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",\r
- &(gdt[thread->Context.nr/8].a),\r
- gdt[thread->Context.nr/8].a,\r
- gdt[thread->Context.nr/8].b);\r
- __asm__("pushfl\n\t"\r
- "cli\n\t"\r
- "ljmp %0\n\t"\r
- "popfl\n\t"\r
- : /* No outputs */\r
- : "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )\r
- : "ax","dx");\r
-}\r
-\r
-static unsigned int allocate_tss_descriptor(void)\r
-/*\r
- * FUNCTION: Allocates a slot within the GDT to describe a TSS\r
- * RETURNS: The offset within the GDT of the slot allocated on succcess\r
- * Zero on failure\r
- */\r
-{\r
- unsigned int i;\r
- for (i=0;i<16;i++)\r
- {\r
- if (gdt[FIRST_TSS_OFFSET + i].a==0 &&\r
- gdt[FIRST_TSS_OFFSET + i].b==0)\r
- {\r
- return(FIRST_TSS_OFFSET + i);\r
- }\r
- }\r
- return(0);\r
-}\r
-\r
-#define FLAG_NT (1<<14)\r
-#define FLAG_VM (1<<17)\r
-#define FLAG_IF (1<<9)\r
-#define FLAG_IOPL ((1<<12)+(1<<13))\r
-\r
-NTSTATUS KeValidateUserContext(PCONTEXT Context)\r
-/*\r
- * FUNCTION: Validates a processor context\r
- * ARGUMENTS:\r
- * Context = Context to validate\r
- * RETURNS: Status\r
- * NOTE: This only validates the context as not violating system security, it\r
- * doesn't guararantee the thread won't crash at some point\r
- * NOTE2: This relies on there only being two selectors which can access \r
- * system space\r
- */\r
-{\r
- if (Context->Eip >= KERNEL_BASE)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (Context->SegCs == KERNEL_CS)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (Context->SegDs == KERNEL_DS)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (Context->SegEs == KERNEL_DS)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (Context->SegFs == KERNEL_DS)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if (Context->SegGs == KERNEL_DS)\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- if ((Context->EFlags & FLAG_IOPL) != 0 ||\r
- (Context->EFlags & FLAG_NT) ||\r
- (Context->EFlags & FLAG_VM) ||\r
- (!(Context->EFlags & FLAG_IF)))\r
- {\r
- return(STATUS_UNSUCCESSFUL);\r
- }\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)\r
-/*\r
- * FUNCTION: Initialize a task with a user mode context\r
- * ARGUMENTS:\r
- * Thread = Thread to initialize\r
- * Context = Processor context to initialize it with\r
- * RETURNS: Status\r
- */\r
-{\r
- unsigned int desc;\r
- unsigned int length;\r
- unsigned int base;\r
- PVOID kernel_stack;\r
- NTSTATUS Status;\r
- PVOID stack_start;\r
- \r
- DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",\r
- Thread,Context);\r
-\r
- assert(sizeof(hal_thread_state)>=0x68);\r
- \r
- if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- desc = allocate_tss_descriptor();\r
- length = sizeof(hal_thread_state) - 1;\r
- base = (unsigned int)(&(Thread->Tcb.Context));\r
- kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);\r
- \r
- /*\r
- * Setup a TSS descriptor\r
- */\r
- gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
- gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)\r
- | (base & 0xff000000);\r
- \r
- stack_start = kernel_stack + 4096 - sizeof(CONTEXT);\r
- memcpy(stack_start, Context, sizeof(CONTEXT));\r
- \r
- /*\r
- * Initialize the thread context\r
- */\r
- memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));\r
- Thread->Tcb.Context.ldt = null_ldt_sel;\r
- Thread->Tcb.Context.eflags = (1<<1) + (1<<9);\r
- Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);\r
- Thread->Tcb.Context.esp0 = stack_start;\r
- Thread->Tcb.Context.ss0 = KERNEL_DS;\r
- Thread->Tcb.Context.esp = stack_start;\r
- Thread->Tcb.Context.ss = KERNEL_DS;\r
- Thread->Tcb.Context.cs = KERNEL_CS;\r
- Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;\r
- Thread->Tcb.Context.io_bitmap[0] = 0xff;\r
- Thread->Tcb.Context.cr3 = \r
- linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);\r
- Thread->Tcb.Context.ds = KERNEL_DS;\r
- Thread->Tcb.Context.es = KERNEL_DS;\r
- Thread->Tcb.Context.fs = KERNEL_DS;\r
- Thread->Tcb.Context.gs = KERNEL_DS;\r
-\r
- Thread->Tcb.Context.nr = desc * 8;\r
- DPRINT("Allocated %x\n",desc*8);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)\r
-/*\r
- * FUNCTION: Initializes the HAL portion of a thread object\r
- * ARGUMENTS:\r
- * thread = Object describes the thread\r
- * fn = Entrypoint for the thread\r
- * StartContext = parameter to pass to the thread entrypoint\r
- * RETURNS: True if the function succeeded\r
- */\r
-{\r
- unsigned int desc = allocate_tss_descriptor();\r
- unsigned int length = sizeof(hal_thread_state) - 1;\r
- unsigned int base = (unsigned int)(&(thread->Tcb.Context));\r
- unsigned int* kernel_stack = ExAllocatePool(NonPagedPool,4096);\r
- \r
- DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",\r
- thread,fn,StartContext);\r
- DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);\r
- \r
- /*\r
- * Make sure\r
- */\r
- assert(sizeof(hal_thread_state)>=0x68);\r
- \r
- /*\r
- * Setup a TSS descriptor\r
- */\r
- gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
- gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)\r
- | (base & 0xff000000);\r
- \r
-// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));\r
-// DPRINT("desc %d\n",desc);\r
- DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",\r
- &(gdt[desc].a),\r
- gdt[desc].a,\r
- gdt[desc].b);\r
- \r
- /*\r
- * Initialize the stack for the thread (including the two arguments to \r
- * the general start routine). \r
- */\r
- kernel_stack[1023] = (unsigned int)StartContext;\r
- kernel_stack[1022] = (unsigned int)fn;\r
- kernel_stack[1021] = NULL; \r
- \r
- /*\r
- * Initialize the thread context\r
- */\r
- memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));\r
- thread->Tcb.Context.ldt = null_ldt_sel;\r
- thread->Tcb.Context.eflags = (1<<1)+(1<<9);\r
- thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);\r
- thread->Tcb.Context.esp0 = &kernel_stack[1021];\r
- thread->Tcb.Context.ss0 = KERNEL_DS;\r
- thread->Tcb.Context.esp = &kernel_stack[1021];\r
- thread->Tcb.Context.ss = KERNEL_DS;\r
- thread->Tcb.Context.cs = KERNEL_CS;\r
- thread->Tcb.Context.eip = (unsigned long)PsBeginThread;\r
- thread->Tcb.Context.io_bitmap[0] = 0xff;\r
- thread->Tcb.Context.cr3 = \r
- linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);\r
- thread->Tcb.Context.ds = KERNEL_DS;\r
- thread->Tcb.Context.es = KERNEL_DS;\r
- thread->Tcb.Context.fs = KERNEL_DS;\r
- thread->Tcb.Context.gs = KERNEL_DS;\r
- thread->Tcb.Context.nr = desc * 8;\r
- DPRINT("Allocated %x\n",desc*8);\r
- \r
-\r
- return(TRUE);\r
-}\r
-\r
-void HalInitFirstTask(PETHREAD thread)\r
-/*\r
- * FUNCTION: Called to setup the HAL portion of a thread object for the \r
- * initial thread\r
- */\r
-{\r
- unsigned int base;\r
- unsigned int length;\r
- unsigned int desc;\r
- \r
- memset(null_ldt,0,sizeof(null_ldt));\r
- desc = allocate_tss_descriptor();\r
- base = (unsigned int)&null_ldt;\r
- length = sizeof(null_ldt) - 1;\r
- gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);\r
- gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)\r
- | (base & 0xff000000);\r
- null_ldt_sel = desc*8;\r
- \r
- /*\r
- * Initialize the thread context\r
- */\r
- HalInitTask(thread,NULL,NULL);\r
-\r
- /*\r
- * Load the task register\r
- */\r
- __asm__("ltr %%ax" \r
- : /* no output */\r
- : "a" (thread->Tcb.Context.nr));\r
- FirstThread = thread;\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/thread.c
+ * PURPOSE: HAL multitasking functions
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * REVISION HISTORY:
+ * 27/06/98: Created
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <internal/ntoskrnl.h>
+#include <internal/ps.h>
+#include <internal/string.h>
+#include <internal/hal.h>
+#include <internal/i386/segment.h>
+#include <internal/mmhal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ***************************************************************/
+
+VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext);
+VOID PsBeginThreadWithContextInternal(VOID);
+
+#define FIRST_TSS_SELECTOR (KERNEL_DS + 0x8)
+#define FIRST_TSS_OFFSET (FIRST_TSS_SELECTOR / 8)
+
+static char null_ldt[8]={0,};
+static unsigned int null_ldt_sel=0;
+static PETHREAD FirstThread=NULL;
+
+/* FUNCTIONS **************************************************************/
+
+void HalTaskSwitch(PKTHREAD thread)
+/*
+ * FUNCTION: Switch tasks
+ * ARGUMENTS:
+ * thread = Thread to switch to
+ * NOTE: This function will not return until the current thread is scheduled
+ * again
+ */
+{
+ DPRINT("Scheduling thread %x\n",thread);
+ DPRINT("Scheduling thread %x\n",thread->Context.nr);
+ DPRINT("previous task %x reserved1 %x esp0 %x ss0 %x\n",
+ thread->Context.previous_task,thread->Context.reserved1,
+ thread->Context.esp0,thread->Context.ss0);
+ DPRINT("reserved2 %x esp1 %x ss1 %x reserved3 %x esp2 %x ss2 %x\n",
+ thread->Context.reserved2,thread->Context.esp1,thread->Context.ss1,
+ thread->Context.reserved3,thread->Context.esp2,thread->Context.ss2);
+ DPRINT("reserved4 %x cr3 %x eip %x eflags %x eax %x\n",
+ thread->Context.reserved4,thread->Context.cr3,thread->Context.eip,
+ thread->Context.eflags,thread->Context.eax);
+ DPRINT("ecx %x edx %x ebx %x esp %x ebp %x esi %x\n",
+ thread->Context.ecx,thread->Context.edx,thread->Context.ebx,
+ thread->Context.esp,thread->Context.ebp,thread->Context.esi);
+ DPRINT("edi %x es %x reserved5 %x cs %x reserved6 %x\n",
+ thread->Context.edi,thread->Context.es,thread->Context.reserved5,
+ thread->Context.cs,thread->Context.reserved6);
+ DPRINT("ss %x reserved7 %x ds %x reserved8 %x fs %x\n",
+ thread->Context.ss,thread->Context.reserved7,thread->Context.ds,
+ thread->Context.reserved8,thread->Context.fs);
+ DPRINT("reserved9 %x gs %x reserved10 %x ldt %x reserved11 %x\n",
+ thread->Context.reserved9,thread->Context.gs,
+ thread->Context.reserved10,thread->Context.ldt,
+ thread->Context.reserved11);
+ DPRINT("trap %x iomap_base %x nr %x io_bitmap[0] %x\n",
+ thread->Context.trap,thread->Context.iomap_base,
+ thread->Context.nr,thread->Context.io_bitmap[0]);
+ DPRINT("&gdt[nr/8].a %.8x gdt[nr/8].a %.8x gdt[nr/8].b %.8x\n",
+ &(gdt[thread->Context.nr/8].a),
+ gdt[thread->Context.nr/8].a,
+ gdt[thread->Context.nr/8].b);
+ __asm__("pushfl\n\t"
+ "cli\n\t"
+ "ljmp %0\n\t"
+ "popfl\n\t"
+ : /* No outputs */
+ : "m" (*(((unsigned char *)(&(thread->Context.nr)))-4) )
+ : "ax","dx");
+}
+
+static unsigned int allocate_tss_descriptor(void)
+/*
+ * FUNCTION: Allocates a slot within the GDT to describe a TSS
+ * RETURNS: The offset within the GDT of the slot allocated on succcess
+ * Zero on failure
+ */
+{
+ unsigned int i;
+ for (i=0;i<16;i++)
+ {
+ if (gdt[FIRST_TSS_OFFSET + i].a==0 &&
+ gdt[FIRST_TSS_OFFSET + i].b==0)
+ {
+ return(FIRST_TSS_OFFSET + i);
+ }
+ }
+ return(0);
+}
+
+#define FLAG_NT (1<<14)
+#define FLAG_VM (1<<17)
+#define FLAG_IF (1<<9)
+#define FLAG_IOPL ((1<<12)+(1<<13))
+
+NTSTATUS KeValidateUserContext(PCONTEXT Context)
+/*
+ * FUNCTION: Validates a processor context
+ * ARGUMENTS:
+ * Context = Context to validate
+ * RETURNS: Status
+ * NOTE: This only validates the context as not violating system security, it
+ * doesn't guararantee the thread won't crash at some point
+ * NOTE2: This relies on there only being two selectors which can access
+ * system space
+ */
+{
+ if (Context->Eip >= KERNEL_BASE)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegCs == KERNEL_CS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegDs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegEs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegFs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if (Context->SegGs == KERNEL_DS)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ if ((Context->EFlags & FLAG_IOPL) != 0 ||
+ (Context->EFlags & FLAG_NT) ||
+ (Context->EFlags & FLAG_VM) ||
+ (!(Context->EFlags & FLAG_IF)))
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS HalReleaseTask(PETHREAD Thread)
+{
+ gdt[Thread->Tcb.Context.nr/8].a=0;
+ gdt[Thread->Tcb.Context.nr/8].b=0;
+ ExFreePool(Thread->Tcb.Context.KernelStackBase);
+ if (Thread->Tcb.Context.SavedKernelStackBase != NULL)
+ {
+ ExFreePool(Thread->Tcb.Context.KernelStackBase);
+ }
+}
+
+NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context)
+/*
+ * FUNCTION: Initialize a task with a user mode context
+ * ARGUMENTS:
+ * Thread = Thread to initialize
+ * Context = Processor context to initialize it with
+ * RETURNS: Status
+ */
+{
+ unsigned int desc;
+ unsigned int length;
+ unsigned int base;
+ PVOID kernel_stack;
+ NTSTATUS Status;
+ PVOID stack_start;
+
+ DPRINT("HalInitTaskWithContext(Thread %x, Context %x)\n",
+ Thread,Context);
+
+ assert(sizeof(hal_thread_state)>=0x68);
+
+ if ((Status=KeValidateUserContext(Context))!=STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ desc = allocate_tss_descriptor();
+ if (desc == 0)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+
+ length = sizeof(hal_thread_state) - 1;
+ base = (unsigned int)(&(Thread->Tcb.Context));
+ kernel_stack = ExAllocatePool(NonPagedPool,PAGESIZE);
+
+ /*
+ * Setup a TSS descriptor
+ */
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
+ | (base & 0xff000000);
+
+ stack_start = kernel_stack + 4096 - sizeof(CONTEXT);
+ memcpy(stack_start, Context, sizeof(CONTEXT));
+
+ /*
+ * Initialize the thread context
+ */
+ memset(&Thread->Tcb.Context,0,sizeof(hal_thread_state));
+ Thread->Tcb.Context.ldt = null_ldt_sel;
+ Thread->Tcb.Context.eflags = (1<<1) + (1<<9);
+ Thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
+ Thread->Tcb.Context.esp0 = (ULONG)stack_start;
+ Thread->Tcb.Context.ss0 = KERNEL_DS;
+ Thread->Tcb.Context.esp = stack_start;
+ Thread->Tcb.Context.ss = KERNEL_DS;
+ Thread->Tcb.Context.cs = KERNEL_CS;
+ Thread->Tcb.Context.eip = PsBeginThreadWithContextInternal;
+ Thread->Tcb.Context.io_bitmap[0] = 0xff;
+ Thread->Tcb.Context.cr3 =
+ linear_to_physical(Thread->ThreadsProcess->Pcb.PageTableDirectory);
+ Thread->Tcb.Context.ds = KERNEL_DS;
+ Thread->Tcb.Context.es = KERNEL_DS;
+ Thread->Tcb.Context.fs = KERNEL_DS;
+ Thread->Tcb.Context.gs = KERNEL_DS;
+
+ Thread->Tcb.Context.nr = desc * 8;
+ Thread->Tcb.Context.KernelStackBase = kernel_stack;
+ Thread->Tcb.Context.SavedKernelEsp = 0;
+ Thread->Tcb.Context.SavedKernelStackBase = NULL;
+
+ return(STATUS_SUCCESS);
+}
+
+BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext)
+/*
+ * FUNCTION: Initializes the HAL portion of a thread object
+ * ARGUMENTS:
+ * thread = Object describes the thread
+ * fn = Entrypoint for the thread
+ * StartContext = parameter to pass to the thread entrypoint
+ * RETURNS: True if the function succeeded
+ */
+{
+ unsigned int desc = allocate_tss_descriptor();
+ unsigned int length = sizeof(hal_thread_state) - 1;
+ unsigned int base = (unsigned int)(&(thread->Tcb.Context));
+ PULONG kernel_stack = ExAllocatePool(NonPagedPool,4096);
+
+ DPRINT("HalInitTask(Thread %x, fn %x, StartContext %x)\n",
+ thread,fn,StartContext);
+ DPRINT("thread->ThreadsProcess %x\n",thread->ThreadsProcess);
+
+ /*
+ * Make sure
+ */
+ assert(sizeof(hal_thread_state)>=0x68);
+
+ /*
+ * Setup a TSS descriptor
+ */
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8900 | (length & 0xf0000)
+ | (base & 0xff000000);
+
+// DPRINT("sizeof(descriptor) %d\n",sizeof(descriptor));
+// DPRINT("desc %d\n",desc);
+ DPRINT("&gdt[desc].a %.8x gdt[desc].a %.8x\ngdt[desc].b %.8x\n",
+ &(gdt[desc].a),
+ gdt[desc].a,
+ gdt[desc].b);
+
+ /*
+ * Initialize the stack for the thread (including the two arguments to
+ * the general start routine).
+ */
+ kernel_stack[1023] = (unsigned int)StartContext;
+ kernel_stack[1022] = (unsigned int)fn;
+ kernel_stack[1021] = NULL;
+
+ /*
+ * Initialize the thread context
+ */
+ memset(&thread->Tcb.Context,0,sizeof(hal_thread_state));
+ thread->Tcb.Context.ldt = null_ldt_sel;
+ thread->Tcb.Context.eflags = (1<<1)+(1<<9);
+ thread->Tcb.Context.iomap_base = FIELD_OFFSET(hal_thread_state,io_bitmap);
+ thread->Tcb.Context.esp0 = &kernel_stack[1021];
+ thread->Tcb.Context.ss0 = KERNEL_DS;
+ thread->Tcb.Context.esp = &kernel_stack[1021];
+ thread->Tcb.Context.ss = KERNEL_DS;
+ thread->Tcb.Context.cs = KERNEL_CS;
+ thread->Tcb.Context.eip = (unsigned long)PsBeginThread;
+ thread->Tcb.Context.io_bitmap[0] = 0xff;
+ thread->Tcb.Context.cr3 =
+ linear_to_physical(thread->ThreadsProcess->Pcb.PageTableDirectory);
+ thread->Tcb.Context.ds = KERNEL_DS;
+ thread->Tcb.Context.es = KERNEL_DS;
+ thread->Tcb.Context.fs = KERNEL_DS;
+ thread->Tcb.Context.gs = KERNEL_DS;
+ thread->Tcb.Context.nr = desc * 8;
+ thread->Tcb.Context.KernelStackBase = kernel_stack;
+ thread->Tcb.Context.SavedKernelEsp = 0;
+ thread->Tcb.Context.SavedKernelStackBase = NULL;
+ DPRINT("Allocated %x\n",desc*8);
+
+
+ return(TRUE);
+}
+
+void HalInitFirstTask(PETHREAD thread)
+/*
+ * FUNCTION: Called to setup the HAL portion of a thread object for the
+ * initial thread
+ */
+{
+ unsigned int base;
+ unsigned int length;
+ unsigned int desc;
+
+ memset(null_ldt,0,sizeof(null_ldt));
+ desc = allocate_tss_descriptor();
+ base = (unsigned int)&null_ldt;
+ length = sizeof(null_ldt) - 1;
+ gdt[desc].a = (length & 0xffff) | ((base & 0xffff) << 16);
+ gdt[desc].b = ((base & 0xff0000)>>16) | 0x8200 | (length & 0xf0000)
+ | (base & 0xff000000);
+ null_ldt_sel = desc*8;
+
+ /*
+ * Initialize the thread context
+ */
+ HalInitTask(thread,NULL,NULL);
+
+ /*
+ * Load the task register
+ */
+ __asm__("ltr %%ax"
+ : /* no output */
+ : "a" (thread->Tcb.Context.nr));
+ FirstThread = thread;
+}
DeviceObject = (PDEVICE_OBJECT)Object;
- DPRINT("DeviceObject %x\n",DeviceObject);
DeviceObject = IoGetAttachedDevice(DeviceObject);
- DPRINT("DeviceObject %x\n",DeviceObject);
if (Status == STATUS_SUCCESS)
{
CHECKPOINT;
FileObject->Flags = FileObject->Flags | FO_DIRECT_DEVICE_OPEN;
FileObject->FileName.Buffer = ExAllocatePool(NonPagedPool,
- ObjectAttributes->ObjectName->Length);
+ (ObjectAttributes->ObjectName->Length+1)*2);
FileObject->FileName.Length = ObjectAttributes->ObjectName->Length;
FileObject->FileName.MaximumLength =
ObjectAttributes->ObjectName->MaximumLength;
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (Irp==NULL)
{
- ExFreePool(FileObject->FileName.Buffer);
ObDereferenceObject(FileObject);
ZwClose(*FileHandle);
*FileHandle=0;
if (Status!=STATUS_SUCCESS)
{
DPRINT("FileObject->FileName.Buffer %x\n",FileObject->FileName.Buffer);
- ExFreePool(FileObject->FileName.Buffer);
ObDereferenceObject(FileObject);
ZwClose(*FileHandle);
*FileHandle=0;
+ return(Status);
}
DPRINT("*FileHandle %x\n",*FileHandle);
+ ObDereferenceObject(FileObject);
return(Status);
FILE_LIST_DIRECTORY,
IoFileType,
UserMode,
- (PVOID *)&FileObject,
+ (PVOID *)&FileObject,
NULL);
if (Status != STATUS_SUCCESS)
{
+ ObDereferenceObject(FileObject);
return(Status);
}
KeInitializeEvent(&Event,NotificationEvent,FALSE);
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (Irp==NULL)
- return STATUS_UNSUCCESSFUL;
+ {
+ ObDereferenceObject(FileObject);
+ return STATUS_UNSUCCESSFUL;
+ }
Irp->UserIosb = IoStatusBlock;
}
Status = IoStatusBlock->Status;
}
+ ObDereferenceObject(FileObject);
return(Status);
}
#include <ddk/ntddk.h>
#include <internal/io.h>
-//#define NDEBUG
+#define NDEBUG
#include <internal/debug.h>
/* TYPES *******************************************************************/
/* FUNCTIONS ****************************************************************/
+VOID IopCloseFile(PVOID ObjectBody)
+{
+ PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
+
+ if (FileObject->FileName.Buffer != NULL)
+ {
+ ExFreePool(FileObject->FileName.Buffer);
+ }
+}
+
VOID IoInit(VOID)
{
OBJECT_ATTRIBUTES attr;
IoDeviceType->NonpagedPoolCharge = sizeof(DEVICE_OBJECT);
IoDeviceType->Dump = NULL;
IoDeviceType->Open = NULL;
- IoDeviceType->Close = NULL;
+ IoDeviceType->Close = NULL;
IoDeviceType->Delete = NULL;
IoDeviceType->Parse = NULL;
IoDeviceType->Security = NULL;
IoFileType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
IoFileType->Dump = NULL;
IoFileType->Open = NULL;
- IoFileType->Close = NULL;
+ IoFileType->Close = IopCloseFile;
IoFileType->Delete = NULL;
IoFileType->Parse = NULL;
IoFileType->Security = NULL;
Stack[1] = TargetThread->Context.eip;
Stack[2] = TargetThread->Context.cs;
Stack[3] = TargetThread->Context.eflags;
- TargetThread->Context.eip = KeApcProlog;
+ TargetThread->Context.eip = (ULONG)KeApcProlog;
TargetThread->Context.eax = (ULONG)Apc;
}
else
Stack[2] = TargetThread->Context.cs;
Stack[1] = TargetThread->Context.eip;
Stack[0] = TargetThread->Context.eax;
- TargetThread->Context.eip = KeApcProlog;
+ TargetThread->Context.eip = (ULONG)KeApcProlog;
TargetThread->Context.eax = (ULONG)Apc;
}
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
KeAcquireDispatcherDatabaseLock(Wait);
-// ret = InterlockedExchange(&(Event->Header.SignalState),1);
- Event->Header.SignalState=1;
+ ret = InterlockedExchange(&(Event->Header.SignalState),1);
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
KeReleaseDispatcherDatabaseLock(Wait);
}
}
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,ticks);
memset(str, 0, sizeof(str));
-// sprintf(str,"%.8u %.8u",EiNrUsedBlocks,KiTimerTicks);
+ sprintf(str,"%.8u %.8u",EiNrUsedBlocks,KiTimerTicks);
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
- sprintf(str,"%.8u %.8u",PiNrThreads,KiTimerTicks);
+// sprintf(str,"%.8u %.8u",PiNrThreads,KiTimerTicks);
for (i=0;i<17;i++)
{
*vidmem=str[i];
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/mm/pool.c\r
- * PURPOSE: Implements the kernel memory pool\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <internal/ntoskrnl.h>\r
-#include <ddk/ntddk.h>\r
-#include <internal/pool.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* GLOBALS *****************************************************************/\r
-\r
-#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))\r
-\r
-/* FUNCTIONS ***************************************************************/\r
-\r
-PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)\r
-/*\r
- * FUNCTION: Allocates pool memory of a specified type and returns a pointer\r
- * to the allocated block. This routine is used for general purpose allocation\r
- * of memory\r
- * ARGUMENTS:\r
- * PoolType\r
- * Specifies the type of memory to allocate which can be one\r
- * of the following:\r
- * \r
- * NonPagedPool\r
- * NonPagedPoolMustSucceed\r
- * NonPagedPoolCacheAligned\r
- * NonPagedPoolCacheAlignedMustS\r
- * PagedPool\r
- * PagedPoolCacheAligned\r
- * \r
- * NumberOfBytes\r
- * Specifies the number of bytes to allocate\r
- * RETURNS: The allocated block on success\r
- * NULL on failure\r
- */\r
-{\r
- PVOID Block;\r
-// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",\r
-// NumberOfBytes,((PULONG)&PoolType)[-1]);\r
- Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);\r
-// DbgPrint("ExAllocatePool() = %x\n",Block);\r
- return(Block);\r
-}\r
-\r
-PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)\r
-{\r
- PVOID Block;\r
- \r
- if (type == NonPagedPoolCacheAligned || \r
- type == NonPagedPoolCacheAlignedMustS)\r
- {\r
- UNIMPLEMENTED;\r
- }\r
- \r
- switch(type)\r
- {\r
- case NonPagedPool:\r
- case NonPagedPoolMustSucceed:\r
- case NonPagedPoolCacheAligned:\r
- case NonPagedPoolCacheAlignedMustS:\r
- Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);\r
- break;\r
- \r
- case PagedPool:\r
- case PagedPoolCacheAligned:\r
- Block = ExAllocatePagedPoolWithTag(type,size,Tag);\r
- break;\r
- \r
- default:\r
- return(NULL);\r
- };\r
- \r
- if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)\r
- && Block==NULL) \r
- {\r
- KeBugCheck(MUST_SUCCEED_POOL_EMPTY);\r
- }\r
- return(Block);\r
-}\r
-\r
-PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,\r
- ULONG Tag)\r
-{\r
- PVOID Block;\r
- PKTHREAD current = KeGetCurrentThread();\r
- \r
- Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);\r
- switch(PoolType)\r
- {\r
- case NonPagedPool:\r
- case NonPagedPoolMustSucceed:\r
- case NonPagedPoolCacheAligned:\r
- case NonPagedPoolCacheAlignedMustS:\r
-// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;\r
- break;\r
- \r
- case PagedPool:\r
- case PagedPoolCacheAligned:\r
-// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;\r
- break; \r
- };\r
- return(Block);\r
-}\r
- \r
-PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)\r
-{\r
- return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/pool.c
+ * PURPOSE: Implements the kernel memory pool
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <internal/ntoskrnl.h>
+#include <ddk/ntddk.h>
+#include <internal/pool.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *****************************************************************/
+
+#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
+
+/* FUNCTIONS ***************************************************************/
+
+PVOID ExAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes)
+/*
+ * FUNCTION: Allocates pool memory of a specified type and returns a pointer
+ * to the allocated block. This routine is used for general purpose allocation
+ * of memory
+ * ARGUMENTS:
+ * PoolType
+ * Specifies the type of memory to allocate which can be one
+ * of the following:
+ *
+ * NonPagedPool
+ * NonPagedPoolMustSucceed
+ * NonPagedPoolCacheAligned
+ * NonPagedPoolCacheAlignedMustS
+ * PagedPool
+ * PagedPoolCacheAligned
+ *
+ * NumberOfBytes
+ * Specifies the number of bytes to allocate
+ * RETURNS: The allocated block on success
+ * NULL on failure
+ */
+{
+ PVOID Block;
+// DbgPrint("ExAllocatePool(NumberOfBytes %d) caller %x\n",
+// NumberOfBytes,((PULONG)&PoolType)[-1]);
+ Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,TAG_NONE);
+// DbgPrint("ExAllocatePool() = %x\n",Block);
+ return(Block);
+}
+
+PVOID ExAllocatePoolWithTag(ULONG type, ULONG size, ULONG Tag)
+{
+ PVOID Block;
+
+ if (type == NonPagedPoolCacheAligned ||
+ type == NonPagedPoolCacheAlignedMustS)
+ {
+ UNIMPLEMENTED;
+ }
+
+ switch(type)
+ {
+ case NonPagedPool:
+ case NonPagedPoolMustSucceed:
+ case NonPagedPoolCacheAligned:
+ case NonPagedPoolCacheAlignedMustS:
+ Block = ExAllocateNonPagedPoolWithTag(type,size,Tag);
+ break;
+
+ case PagedPool:
+ case PagedPoolCacheAligned:
+ Block = ExAllocatePagedPoolWithTag(type,size,Tag);
+ break;
+
+ default:
+ return(NULL);
+ };
+
+ if ((type==NonPagedPoolMustSucceed || type==NonPagedPoolCacheAlignedMustS)
+ && Block==NULL)
+ {
+ KeBugCheck(MUST_SUCCEED_POOL_EMPTY);
+ }
+ return(Block);
+}
+
+PVOID ExAllocatePoolWithQuotaTag(POOL_TYPE PoolType, ULONG NumberOfBytes,
+ ULONG Tag)
+{
+ PVOID Block;
+ PKTHREAD current = KeGetCurrentThread();
+
+ Block = ExAllocatePoolWithTag(PoolType,NumberOfBytes,Tag);
+ switch(PoolType)
+ {
+ case NonPagedPool:
+ case NonPagedPoolMustSucceed:
+ case NonPagedPoolCacheAligned:
+ case NonPagedPoolCacheAlignedMustS:
+// current->NPagedPoolQuota = current->NPagedPoolQuota - NumberOfBytes;
+ break;
+
+ case PagedPool:
+ case PagedPoolCacheAligned:
+// current->PagedPoolQuota = current->PagedPoolQuota - NumberOfBytes;
+ break;
+ };
+ return(Block);
+}
+
+PVOID ExAllocatePoolWithQuota(POOL_TYPE PoolType, ULONG NumberOfBytes)
+{
+ return(ExAllocatePoolWithQuotaTag(PoolType,NumberOfBytes,TAG_NONE));
+}
current = CONTAINING_RECORD(current_entry,OBJECT_HEADER,Entry);
DPRINT("Scanning %w\n",current->Name.Buffer);
DirObjInformation[i].ObjectName.Buffer =
- ExAllocatePool(NonPagedPool, current->Name.Length + sizeof(WCHAR));
+ ExAllocatePool(NonPagedPool,(current->Name.Length+1)*2);
DirObjInformation[i].ObjectName.Length = current->Name.Length;
- DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length + sizeof(WCHAR);
+ DirObjInformation[i].ObjectName.MaximumLength = current->Name.Length;
DPRINT("DirObjInformation[i].ObjectName.Buffer %x\n",
DirObjInformation[i].ObjectName.Buffer);
RtlCopyUnicodeString(&DirObjInformation[i].ObjectName,
return(Status);
}
-
UNIMPLEMENTED
}
+VOID ObMakeTemporaryObject(PVOID ObjectBody)
+{
+ POBJECT_HEADER ObjectHeader;
+
+ ObjectHeader = BODY_TO_HEADER(ObjectBody);
+ ObjectHeader->Permanent = FALSE;
+}
+
NTSTATUS NtMakeTemporaryObject(HANDLE Handle)
{
return(ZwMakeTemporaryObject(Handle));
// DbgPrint("ObjectAttributes->ObjectName->MaximumLength %d\n",
// ObjectAttributes->ObjectName->MaximumLength);
Buffer = ExAllocatePool(NonPagedPool,
- ((ObjectAttributes->ObjectName->Length + 1) *
- sizeof(WCHAR)));
+ ((ObjectAttributes->ObjectName->Length+1)*2));
if (Buffer==NULL)
{
return(NULL);
}
memcpy(Buffer, ObjectAttributes->ObjectName->Buffer,
- (ObjectAttributes->ObjectName->Length + 1) * sizeof(WCHAR));
+ (ObjectAttributes->ObjectName->Length+1)*2);
/*
* Seperate the name into a path and name
NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header)
{
+ DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n",
+ Header,Header->RefCount,Header->HandleCount);
+
+ if (Header->RefCount < 0 || Header->HandleCount < 0)
+ {
+ KeBugCheck(0);
+ }
+
if (Header->RefCount == 0 && Header->HandleCount == 0 &&
!Header->Permanent)
{
+ if (Header->ObjectType != NULL &&
+ Header->ObjectType->Close != NULL)
+ {
+ Header->ObjectType->Close(HEADER_TO_BODY(Header));
+ }
if (Header->Name.Buffer != NULL)
{
ObRemoveEntry(Header);
}
+ DPRINT("ObPerformRetentionChecks() = Freeing object\n");
ExFreePool(Header);
}
return(STATUS_SUCCESS);
assert_irql(PASSIVE_LEVEL);
+ DPRINT("ZwClose(Handle %x)\n",Handle);
+
HandleRep = ObTranslateHandle(KeGetCurrentProcess(),Handle);
if (HandleRep == NULL)
{
return(STATUS_SUCCESS);
}
-
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/ps/kill.c\r
- * PURPOSE: Terminating a thread\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * UPDATE HISTORY:\r
- * Created 22/05/98\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <ddk/ntddk.h>\r
-#include <internal/ps.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* GLBOALS *******************************************************************/\r
-\r
-extern ULONG PiNrThreads;\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,\r
- IN NTSTATUS ExitStatus)\r
-{\r
- return(ZwTerminateProcess(ProcessHandle,ExitStatus));\r
-}\r
-\r
-NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,\r
- IN NTSTATUS ExitStatus)\r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- PEPROCESS Process;\r
- KIRQL oldlvl;\r
-\r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_TERMINATE,\r
- PsProcessType,\r
- UserMode,\r
- (PVOID*)&Process,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
-\r
- PiTerminateProcessThreads(Process, ExitStatus);\r
- KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);\r
- KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader);\r
- Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;\r
- if (PsGetCurrentThread()->ThreadsProcess == Process)\r
- {\r
- KeLowerIrql(oldlvl);\r
- PsTerminateSystemThread(ExitStatus);\r
- }\r
- KeLowerIrql(oldlvl);\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-\r
-NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,\r
- IN NTSTATUS ExitStatus)\r
-{\r
- return(ZwTerminateThread(ThreadHandle,ExitStatus));\r
-}\r
-\r
-NTSTATUS STDCALL ZwTerminateThread(IN HANDLE ThreadHandle, \r
- IN NTSTATUS ExitStatus)\r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- Status = ObReferenceObjectByHandle(ThreadHandle,\r
- THREAD_TERMINATE,\r
- PsThreadType,\r
- UserMode,\r
- (PVOID*)&Thread,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
-\r
- PsTerminateThread(Thread);\r
-}\r
-\r
-VOID PsTerminateThread(PETHREAD Thread, NTSTATUS ExitStatus)\r
-{\r
- if (Thread == PsGetCurrentThread())\r
- {\r
- PsTerminateSystemThread(ExitStatus);\r
- }\r
- else\r
- {\r
- UNIMPLEMENTED;\r
- }\r
-}\r
-\r
-VOID PsReleaseThread(PETHREAD Thread)\r
-{\r
- DPRINT("PsReleaseThread(Thread %x)\n",Thread);\r
- \r
- RemoveEntryList(&Thread->Tcb.Entry);\r
- ObDereferenceObject(Thread);\r
-}\r
-\r
-\r
-NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)\r
-/*\r
- * FUNCTION: Terminates the current thread\r
- * ARGUMENTS:\r
- * ExitStatus = Status to pass to the creater\r
- * RETURNS: Doesn't\r
- */\r
-{\r
- KIRQL oldlvl;\r
- PETHREAD CurrentThread;\r
- \r
- PiNrThreads--;\r
- \r
- CurrentThread = PsGetCurrentThread();\r
- \r
- CurrentThread->ExitStatus = ExitStatus;\r
- \r
- DPRINT("terminating %x\n",CurrentThread);\r
- ObDereferenceObject(CurrentThread->ThreadsProcess);\r
- KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);\r
- CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;\r
- ZwYieldExecution();\r
- for(;;);\r
-}\r
-\r
-NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)\r
-{\r
- return(ZwRegisterThreadTerminatePort(TerminationPort));\r
-}\r
-\r
-NTSTATUS STDCALL ZwRegisterThreadTerminatePort(HANDLE TerminationPort)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ps/kill.c
+ * PURPOSE: Terminating a thread
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLBOALS *******************************************************************/
+
+extern ULONG PiNrThreads;
+
+/* FUNCTIONS *****************************************************************/
+
+VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
+{
+ KIRQL oldlvl;
+ PETHREAD CurrentThread;
+
+ PiNrThreads--;
+
+ CurrentThread = PsGetCurrentThread();
+
+ CurrentThread->ExitStatus = ExitStatus;
+
+ DPRINT("terminating %x\n",CurrentThread);
+ ObDereferenceObject(CurrentThread->ThreadsProcess);
+ KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
+ CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
+ ZwYieldExecution();
+ for(;;);
+}
+
+VOID PsTerminateOtherThread(PETHREAD Thread, NTSTATUS ExitStatus)
+{
+ UNIMPLEMENTED;
+}
+
+
+NTSTATUS STDCALL NtTerminateProcess(IN HANDLE ProcessHandle,
+ IN NTSTATUS ExitStatus)
+{
+ return(ZwTerminateProcess(ProcessHandle,ExitStatus));
+}
+
+NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle,
+ IN NTSTATUS ExitStatus)
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+ PEPROCESS Process;
+ KIRQL oldlvl;
+
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_TERMINATE,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Process,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ PiTerminateProcessThreads(Process, ExitStatus);
+ KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
+ KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader);
+ Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
+ if (PsGetCurrentThread()->ThreadsProcess == Process)
+ {
+ KeLowerIrql(oldlvl);
+ PsTerminateCurrentThread(ExitStatus);
+ }
+ KeLowerIrql(oldlvl);
+ return(STATUS_SUCCESS);
+}
+
+
+NTSTATUS STDCALL NtTerminateThread(IN HANDLE ThreadHandle,
+ IN NTSTATUS ExitStatus)
+{
+ return(ZwTerminateThread(ThreadHandle,ExitStatus));
+}
+
+NTSTATUS STDCALL ZwTerminateThread(IN HANDLE ThreadHandle,
+ IN NTSTATUS ExitStatus)
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ Status = ObReferenceObjectByHandle(ThreadHandle,
+ THREAD_TERMINATE,
+ PsThreadType,
+ UserMode,
+ (PVOID*)&Thread,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ if (Thread == PsGetCurrentThread())
+ {
+ PsTerminateCurrentThread(ExitStatus);
+ }
+ else
+ {
+ PsTerminateOtherThread(Thread, ExitStatus);
+ }
+}
+
+VOID PsReleaseThread(PETHREAD Thread)
+{
+ DPRINT("PsReleaseThread(Thread %x)\n",Thread);
+
+ RemoveEntryList(&Thread->Tcb.Entry);
+ HalReleaseTask(Thread);
+ ObDereferenceObject(Thread);
+}
+
+
+NTSTATUS PsTerminateSystemThread(NTSTATUS ExitStatus)
+/*
+ * FUNCTION: Terminates the current thread
+ * ARGUMENTS:
+ * ExitStatus = Status to pass to the creater
+ * RETURNS: Doesn't
+ */
+{
+ PsTerminateCurrentThread(ExitStatus);
+}
+
+NTSTATUS STDCALL NtRegisterThreadTerminatePort(HANDLE TerminationPort)
+{
+ return(ZwRegisterThreadTerminatePort(TerminationPort));
+}
+
+NTSTATUS STDCALL ZwRegisterThreadTerminatePort(HANDLE TerminationPort)
+{
+ UNIMPLEMENTED;
+}
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/ps/thread.c\r
- * PURPOSE: Thread managment\r
- * PROGRAMMER: David Welch (welch@mcmail.com)\r
- * REVISION HISTORY: \r
- * 23/06/98: Created\r
- */\r
-\r
-/*\r
- * NOTE:\r
- * \r
- * All of the routines that manipulate the thread queue synchronize on\r
- * a single spinlock\r
- * \r
- */\r
-\r
-/* INCLUDES ****************************************************************/\r
-\r
-#include <windows.h>\r
-#include <ddk/ntddk.h>\r
-#include <internal/ke.h>\r
-#include <internal/ob.h>\r
-#include <internal/string.h>\r
-#include <internal/hal.h>\r
-#include <internal/ps.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-/* TYPES *******************************************************************/\r
-\r
-/* GLOBALS ******************************************************************/\r
-\r
-POBJECT_TYPE PsThreadType = NULL;\r
-\r
-#define NR_THREAD_PRIORITY_LEVELS (31)\r
-#define THREAD_PRIORITY_MAX (15)\r
-\r
-static KSPIN_LOCK ThreadListLock = {0,};\r
-\r
-/*\r
- * PURPOSE: List of threads associated with each priority level\r
- */\r
-static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]={{NULL,NULL},};\r
-static BOOLEAN DoneInitYet = FALSE;\r
-ULONG PiNrThreads = 0;\r
-ULONG PiNrRunnableThreads = 0;\r
-\r
-static PETHREAD CurrentThread = NULL;\r
-\r
-static ULONG NextThreadUniqueId = 0;\r
-\r
-/* FUNCTIONS ***************************************************************/\r
-\r
-PKTHREAD KeGetCurrentThread(VOID)\r
-{\r
- return(&(CurrentThread->Tcb));\r
-}\r
-\r
-PETHREAD PsGetCurrentThread(VOID)\r
-{\r
- return((PETHREAD)KeGetCurrentThread());\r
-}\r
-\r
-VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)\r
-{\r
- KIRQL oldlvl;\r
- PLIST_ENTRY current_entry;\r
- PETHREAD current;\r
- ULONG i;\r
-\r
- KeAcquireSpinLock(&ThreadListLock, &oldlvl);\r
-\r
- for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)\r
- {\r
- current_entry = PriorityListHead[i].Flink;\r
- while (current_entry != &PriorityListHead[i])\r
- {\r
- current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);\r
- if (current->ThreadsProcess == Process &&\r
- current != PsGetCurrentThread())\r
- {\r
- PsTerminateThread(current, ExitStatus);\r
- }\r
- current_entry = current_entry->Flink;\r
- }\r
- }\r
-\r
- KeReleaseSpinLock(&ThreadListLock, oldlvl);\r
-}\r
-\r
-static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)\r
-{\r
- KIRQL oldlvl;\r
- \r
- DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,\r
- Thread);\r
- \r
- KeAcquireSpinLock(&ThreadListLock,&oldlvl);\r
- InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],\r
- &Thread->Tcb.Entry);\r
- KeReleaseSpinLock(&ThreadListLock,oldlvl);\r
-}\r
-\r
-VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)\r
-{\r
- NTSTATUS Ret;\r
- \r
- KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);\r
- Ret = StartRoutine(StartContext);\r
- PsTerminateSystemThread(Ret);\r
- for(;;);\r
-}\r
-\r
-static PETHREAD PsScanThreadList(KPRIORITY Priority)\r
-{\r
- PLIST_ENTRY current_entry;\r
- PETHREAD current;\r
- PETHREAD oldest = NULL;\r
- ULONG oldest_time = 0;\r
- \r
-// DPRINT("PsScanThreadList(Priority %d)\n",Priority);\r
- \r
- current_entry = PriorityListHead[THREAD_PRIORITY_MAX+Priority].Flink;\r
- while (current_entry != &PriorityListHead[THREAD_PRIORITY_MAX+Priority])\r
- {\r
- current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);\r
-\r
- if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED &&\r
- current != CurrentThread)\r
- {\r
- PsReleaseThread(current);\r
- }\r
-\r
- if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)\r
- {\r
- if (oldest == NULL || oldest_time > current->Tcb.LastTick)\r
- {\r
- oldest = current;\r
- oldest_time = current->Tcb.LastTick;\r
- }\r
- }\r
- current_entry = current_entry->Flink;\r
- }\r
-// DPRINT("PsScanThreadList() = %x\n",oldest);\r
- return(oldest);\r
-}\r
-\r
-VOID PsDispatchThread(VOID)\r
-{\r
- KPRIORITY CurrentPriority;\r
- PETHREAD Candidate;\r
- KIRQL irql;\r
- LARGE_INTEGER TickCount;\r
- \r
- KeAcquireSpinLock(&ThreadListLock,&irql);\r
- \r
- if (!DoneInitYet)\r
- {\r
- return;\r
- }\r
- \r
- DPRINT("PsDispatchThread() Current %x\n",CurrentThread);\r
- \r
- if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING) \r
- {\r
- CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE;\r
- }\r
- \r
- for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL; \r
- CurrentPriority>=THREAD_PRIORITY_IDLE;\r
- CurrentPriority--)\r
- {\r
- Candidate = PsScanThreadList(CurrentPriority);\r
- if (Candidate == CurrentThread)\r
- {\r
- DPRINT("Scheduling current thread\n");\r
- KeQueryTickCount(&TickCount);\r
- CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);\r
- CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
- KeReleaseSpinLock(&ThreadListLock,irql);\r
- return;\r
- }\r
- if (Candidate != NULL)\r
- { \r
- DPRINT("Scheduling %x\n",Candidate);\r
- \r
- Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
- \r
- KeQueryTickCount(&TickCount);\r
- CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);\r
- \r
- CurrentThread = Candidate;\r
- \r
- HalTaskSwitch(&CurrentThread->Tcb);\r
- KeReleaseSpinLock(&ThreadListLock,irql);\r
- return;\r
- }\r
- }\r
- DbgPrint("CRITICAL: No threads are runnable\n");\r
- KeBugCheck(0);\r
-}\r
-\r
-NTSTATUS PsInitializeThread(HANDLE ProcessHandle, \r
- PETHREAD* ThreadPtr,\r
- PHANDLE ThreadHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ThreadAttributes)\r
-{\r
- ULONG ThreadId;\r
- ULONG ProcessId;\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- PiNrThreads++;\r
- \r
- Thread = ObGenericCreateObject(ThreadHandle,\r
- DesiredAccess,\r
- ThreadAttributes,\r
- PsThreadType);\r
- DPRINT("Thread = %x\n",Thread);\r
- Thread->Tcb.LastTick = 0;\r
- Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED;\r
- Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL;\r
- Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL;\r
- Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));\r
- Thread->Tcb.SuspendCount = 1;\r
- if (ProcessHandle!=NULL)\r
- {\r
- Status = ObReferenceObjectByHandle(ProcessHandle,\r
- PROCESS_CREATE_THREAD,\r
- PsProcessType,\r
- UserMode,\r
- (PVOID*)&Thread->ThreadsProcess,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- DPRINT("Failed at %s:%d\n",__FILE__,__LINE__);\r
- return(Status);\r
- }\r
- }\r
- else\r
- {\r
- Thread->ThreadsProcess=SystemProcess;\r
- ObReferenceObjectByPointer(Thread->ThreadsProcess,\r
- PROCESS_CREATE_THREAD,\r
- PsProcessType,\r
- UserMode);\r
- }\r
- ObReferenceObjectByPointer(Thread->ThreadsProcess,\r
- PROCESS_CREATE_THREAD,\r
- PsProcessType,\r
- UserMode);\r
- InitializeListHead(Thread->Tcb.ApcList);\r
- InitializeListHead(&(Thread->IrpList));\r
- Thread->Cid.UniqueThread=InterlockedIncrement(&NextThreadUniqueId);\r
- ObReferenceObjectByPointer(Thread,\r
- THREAD_ALL_ACCESS,\r
- PsThreadType,\r
- UserMode);\r
- PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);\r
- \r
- *ThreadPtr = Thread;\r
- \r
- ObDereferenceObject(Thread->ThreadsProcess); \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-VOID PsResumeThread(PETHREAD Thread)\r
-{\r
- DPRINT("PsResumeThread(Thread %x)\n",Thread);\r
- \r
- Thread->Tcb.SuspendCount--;\r
- DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount);\r
- DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n",\r
- Thread->Tcb.ThreadState,THREAD_STATE_RUNNING);\r
- if (Thread->Tcb.SuspendCount <= 0 && \r
- Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)\r
- {\r
- DPRINT("Setting thread to runnable\n");\r
- Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;\r
- }\r
- DPRINT("Finished PsResumeThread()\n");\r
-}\r
-\r
-VOID PsSuspendThread(PETHREAD Thread)\r
-{\r
- DPRINT("PsSuspendThread(Thread %x)\n",Thread);\r
- Thread->Tcb.SuspendCount++;\r
- if (Thread->Tcb.SuspendCount > 0)\r
- {\r
- Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;\r
- if (Thread == CurrentThread)\r
- {\r
- PsDispatchThread();\r
- }\r
- }\r
-}\r
-\r
-void PsInitThreadManagment(void)\r
-/*\r
- * FUNCTION: Initialize thread managment\r
- */\r
-{\r
- PETHREAD FirstThread;\r
- ULONG i;\r
- ANSI_STRING AnsiString;\r
- HANDLE FirstThreadHandle;\r
- \r
- KeInitializeSpinLock(&ThreadListLock);\r
- for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)\r
- {\r
- InitializeListHead(&PriorityListHead[i]);\r
- }\r
- \r
- PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));\r
- \r
- RtlInitAnsiString(&AnsiString,"Thread");\r
- RtlAnsiStringToUnicodeString(&PsThreadType->TypeName,&AnsiString,TRUE);\r
- \r
- PsThreadType->TotalObjects = 0;\r
- PsThreadType->TotalHandles = 0;\r
- PsThreadType->MaxObjects = 0;\r
- PsThreadType->MaxHandles = 0;\r
- PsThreadType->PagedPoolCharge = 0;\r
- PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);\r
- PsThreadType->Dump = NULL;\r
- PsThreadType->Open = NULL;\r
- PsThreadType->Close = NULL;\r
- PsThreadType->Delete = NULL;\r
- PsThreadType->Parse = NULL;\r
- PsThreadType->Security = NULL;\r
- PsThreadType->QueryName = NULL;\r
- PsThreadType->OkayToClose = NULL;\r
- \r
- PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,\r
- THREAD_ALL_ACCESS,NULL);\r
- HalInitFirstTask(FirstThread);\r
- FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING;\r
- FirstThread->Tcb.SuspendCount = 0;\r
-\r
- DPRINT("FirstThread %x\n",FirstThread);\r
- \r
- CurrentThread = FirstThread;\r
- \r
- DoneInitYet = TRUE;\r
-}\r
-\r
-NTSTATUS NtCreateThread(PHANDLE ThreadHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes,\r
- HANDLE ProcessHandle,\r
- PCLIENT_ID Client,\r
- PCONTEXT ThreadContext,\r
- PINITIAL_TEB InitialTeb,\r
- BOOLEAN CreateSuspended)\r
-{\r
- return(ZwCreateThread(ThreadHandle,\r
- DesiredAccess,\r
- ObjectAttributes,\r
- ProcessHandle,\r
- Client,\r
- ThreadContext,\r
- InitialTeb,\r
- CreateSuspended));\r
-}\r
-\r
-NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes,\r
- HANDLE ProcessHandle,\r
- PCLIENT_ID Client,\r
- PCONTEXT ThreadContext,\r
- PINITIAL_TEB InitialTeb,\r
- BOOLEAN CreateSuspended)\r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- DPRINT("ZwCreateThread(ThreadHandle %x, PCONTEXT %x)\n",\r
- ThreadHandle,ThreadContext);\r
- \r
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,\r
- DesiredAccess,ObjectAttributes);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- HalInitTaskWithContext(Thread,ThreadContext);\r
- Thread->StartAddress=NULL;\r
-\r
- if (Client!=NULL)\r
- {\r
- *Client=Thread->Cid;\r
- } \r
- \r
- if (!CreateSuspended)\r
- {\r
- DPRINT("Not creating suspended\n");\r
- PsResumeThread(Thread);\r
- }\r
- DPRINT("Finished PsCreateThread()\n");\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,\r
- ACCESS_MASK DesiredAccess,\r
- POBJECT_ATTRIBUTES ObjectAttributes,\r
- HANDLE ProcessHandle,\r
- PCLIENT_ID ClientId,\r
- PKSTART_ROUTINE StartRoutine,\r
- PVOID StartContext)\r
-/*\r
- * FUNCTION: Creates a thread which executes in kernel mode\r
- * ARGUMENTS:\r
- * ThreadHandle (OUT) = Caller supplied storage for the returned thread \r
- * handle\r
- * DesiredAccess = Requested access to the thread\r
- * ObjectAttributes = Object attributes (optional)\r
- * ProcessHandle = Handle of process thread will run in\r
- * NULL to use system process\r
- * ClientId (OUT) = Caller supplied storage for the returned client id\r
- * of the thread (optional)\r
- * StartRoutine = Entry point for the thread\r
- * StartContext = Argument supplied to the thread when it begins\r
- * execution\r
- * RETURNS: Success or failure status\r
- */\r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",\r
- ThreadHandle,ProcessHandle);\r
- \r
- Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,\r
- DesiredAccess,ObjectAttributes);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- Thread->StartAddress=StartRoutine;\r
- HalInitTask(Thread,StartRoutine,StartContext);\r
-\r
- if (ClientId!=NULL)\r
- {\r
- *ClientId=Thread->Cid;\r
- } \r
-\r
- PsResumeThread(Thread);\r
- \r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)\r
-{\r
- KPRIORITY OldPriority;\r
- OldPriority = Thread->CurrentPriority;\r
- Thread->CurrentPriority = Priority;\r
-\r
- RemoveEntryList(&Thread->Entry);\r
- PsInsertIntoThreadList(Thread->CurrentPriority,\r
- CONTAINING_RECORD(Thread,ETHREAD,Tcb));\r
- \r
- return(OldPriority);\r
-}\r
-\r
-NTSTATUS STDCALL NtAlertResumeThread(IN HANDLE ThreadHandle,\r
- OUT PULONG SuspendCount)\r
-{\r
- return(ZwAlertResumeThread(ThreadHandle,SuspendCount));\r
-}\r
-\r
-NTSTATUS STDCALL ZwAlertResumeThread(IN HANDLE ThreadHandle,\r
- OUT PULONG SuspendCount)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtAlertThread(IN HANDLE ThreadHandle)\r
-{\r
- return(ZwAlertThread(ThreadHandle));\r
-}\r
-\r
-NTSTATUS STDCALL ZwAlertThread(IN HANDLE ThreadHandle)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtGetContextThread(IN HANDLE ThreadHandle, \r
- OUT PCONTEXT Context)\r
-{\r
- return(ZwGetContextThread(ThreadHandle,Context));\r
-}\r
-\r
-NTSTATUS STDCALL ZwGetContextThread(IN HANDLE ThreadHandle, \r
- OUT PCONTEXT Context)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes,\r
- IN PCLIENT_ID ClientId)\r
-{\r
- return(ZwOpenThread(ThreadHandle,\r
- DesiredAccess,\r
- ObjectAttributes,\r
- ClientId));\r
-}\r
-\r
-NTSTATUS STDCALL ZwOpenThread(OUT PHANDLE ThreadHandle,\r
- IN ACCESS_MASK DesiredAccess,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes,\r
- IN PCLIENT_ID ClientId)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtResumeThread(IN HANDLE ThreadHandle,\r
- IN PULONG SuspendCount)\r
-{\r
- return(ZwResumeThread(ThreadHandle,SuspendCount));\r
-}\r
-\r
-NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle,\r
- IN PULONG SuspendCount)\r
-/*\r
- * FUNCTION: Decrements a thread's resume count\r
- * ARGUMENTS: \r
- * ThreadHandle = Handle to the thread that should be resumed\r
- * ResumeCount = The resulting resume count.\r
- * REMARK:\r
- * A thread is resumed if its suspend count is 0. This procedure maps to\r
- * the win32 ResumeThread function. ( documentation about the the suspend count can be found here aswell )\r
- * RETURNS: Status\r
- */\r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- Status = ObReferenceObjectByHandle(ThreadHandle,\r
- THREAD_SUSPEND_RESUME,\r
- PsThreadType,\r
- UserMode,\r
- (PVOID*)&Thread,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- (*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);\r
- if (Thread->Tcb.SuspendCount <= 0)\r
- {\r
- Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;\r
- }\r
- \r
- ObDereferenceObject(Thread);\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS STDCALL NtSetContextThread(IN HANDLE ThreadHandle,\r
- IN PCONTEXT Context)\r
-{\r
- return(ZwSetContextThread(ThreadHandle,Context));\r
-}\r
-\r
-NTSTATUS STDCALL ZwSetContextThread(IN HANDLE ThreadHandle,\r
- IN PCONTEXT Context)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtSuspendThread(IN HANDLE ThreadHandle,\r
- IN PULONG PreviousSuspendCount)\r
-{\r
- return(ZwSuspendThread(ThreadHandle,PreviousSuspendCount));\r
-}\r
-\r
-NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle,\r
- IN PULONG PreviousSuspendCount)\r
-/*\r
- * FUNCTION: Increments a thread's suspend count\r
- * ARGUMENTS: \r
- * ThreadHandle = Handle to the thread that should be resumed\r
- * PreviousSuspendCount = The resulting/previous suspend count.\r
- * REMARK:\r
- * A thread will be suspended if its suspend count is greater than 0. \r
- * This procedure maps to the win32 SuspendThread function. ( \r
- * documentation about the the suspend count can be found here aswell )\r
- * The suspend count is not increased if it is greater than \r
- * MAXIMUM_SUSPEND_COUNT.\r
- * RETURNS: Status\r
- */ \r
-{\r
- PETHREAD Thread;\r
- NTSTATUS Status;\r
- \r
- Status = ObReferenceObjectByHandle(ThreadHandle,\r
- THREAD_SUSPEND_RESUME,\r
- PsThreadType,\r
- UserMode,\r
- (PVOID*)&Thread,\r
- NULL);\r
- if (Status != STATUS_SUCCESS)\r
- {\r
- return(Status);\r
- }\r
- \r
- (*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount);\r
- if (Thread->Tcb.SuspendCount > 0)\r
- {\r
- Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;\r
- if (Thread == PsGetCurrentThread())\r
- {\r
- PsDispatchThread();\r
- }\r
- }\r
- \r
- ObDereferenceObject(Thread);\r
- return(STATUS_SUCCESS);\r
-}\r
-\r
-NTSTATUS STDCALL NtContinue(IN PCONTEXT Context, IN CINT IrqLevel)\r
-{\r
- return(ZwContinue(Context,IrqLevel));\r
-}\r
-\r
-NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-NTSTATUS STDCALL NtYieldExecution(VOID)\r
-{\r
- return(ZwYieldExecution());\r
-}\r
-\r
-NTSTATUS STDCALL ZwYieldExecution(VOID)\r
-{\r
- PsDispatchThread();\r
- return(STATUS_SUCCESS);\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ps/thread.c
+ * PURPOSE: Thread managment
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * REVISION HISTORY:
+ * 23/06/98: Created
+ */
+
+/*
+ * NOTE:
+ *
+ * All of the routines that manipulate the thread queue synchronize on
+ * a single spinlock
+ *
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <internal/ke.h>
+#include <internal/ob.h>
+#include <internal/string.h>
+#include <internal/hal.h>
+#include <internal/ps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* TYPES *******************************************************************/
+
+/* GLOBALS ******************************************************************/
+
+POBJECT_TYPE PsThreadType = NULL;
+
+#define NR_THREAD_PRIORITY_LEVELS (31)
+#define THREAD_PRIORITY_MAX (15)
+
+static KSPIN_LOCK ThreadListLock = {0,};
+
+/*
+ * PURPOSE: List of threads associated with each priority level
+ */
+static LIST_ENTRY PriorityListHead[NR_THREAD_PRIORITY_LEVELS]={{NULL,NULL},};
+static BOOLEAN DoneInitYet = FALSE;
+ULONG PiNrThreads = 0;
+ULONG PiNrRunnableThreads = 0;
+
+static PETHREAD CurrentThread = NULL;
+
+static ULONG NextThreadUniqueId = 0;
+
+/* FUNCTIONS ***************************************************************/
+
+PKTHREAD KeGetCurrentThread(VOID)
+{
+ return(&(CurrentThread->Tcb));
+}
+
+PETHREAD PsGetCurrentThread(VOID)
+{
+ return((PETHREAD)KeGetCurrentThread());
+}
+
+VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
+{
+ KIRQL oldlvl;
+ PLIST_ENTRY current_entry;
+ PETHREAD current;
+ ULONG i;
+
+ KeAcquireSpinLock(&ThreadListLock, &oldlvl);
+
+ for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)
+ {
+ current_entry = PriorityListHead[i].Flink;
+ while (current_entry != &PriorityListHead[i])
+ {
+ current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);
+ if (current->ThreadsProcess == Process &&
+ current != PsGetCurrentThread())
+ {
+ PsTerminateOtherThread(current, ExitStatus);
+ }
+ current_entry = current_entry->Flink;
+ }
+ }
+
+ KeReleaseSpinLock(&ThreadListLock, oldlvl);
+}
+
+static VOID PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
+{
+ KIRQL oldlvl;
+
+ DPRINT("PsInsertIntoThreadList(Priority %x, Thread %x)\n",Priority,
+ Thread);
+
+ KeAcquireSpinLock(&ThreadListLock,&oldlvl);
+ InsertTailList(&PriorityListHead[THREAD_PRIORITY_MAX+Priority],
+ &Thread->Tcb.Entry);
+ KeReleaseSpinLock(&ThreadListLock,oldlvl);
+}
+
+VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
+{
+ NTSTATUS Ret;
+
+ KeReleaseSpinLock(&ThreadListLock,PASSIVE_LEVEL);
+ Ret = StartRoutine(StartContext);
+ PsTerminateSystemThread(Ret);
+ for(;;);
+}
+
+static PETHREAD PsScanThreadList(KPRIORITY Priority)
+{
+ PLIST_ENTRY current_entry;
+ PETHREAD current;
+ PETHREAD oldest = NULL;
+ ULONG oldest_time = 0;
+
+// DPRINT("PsScanThreadList(Priority %d)\n",Priority);
+
+ current_entry = PriorityListHead[THREAD_PRIORITY_MAX+Priority].Flink;
+ while (current_entry != &PriorityListHead[THREAD_PRIORITY_MAX+Priority])
+ {
+ current = CONTAINING_RECORD(current_entry,ETHREAD,Tcb.Entry);
+
+ if (current->Tcb.ThreadState == THREAD_STATE_TERMINATED &&
+ current != CurrentThread)
+ {
+ PsReleaseThread(current);
+ }
+
+ if (current->Tcb.ThreadState == THREAD_STATE_RUNNABLE)
+ {
+ if (oldest == NULL || oldest_time > current->Tcb.LastTick)
+ {
+ oldest = current;
+ oldest_time = current->Tcb.LastTick;
+ }
+ }
+ current_entry = current_entry->Flink;
+ }
+// DPRINT("PsScanThreadList() = %x\n",oldest);
+ return(oldest);
+}
+
+VOID PsDispatchThread(VOID)
+{
+ KPRIORITY CurrentPriority;
+ PETHREAD Candidate;
+ KIRQL irql;
+ LARGE_INTEGER TickCount;
+
+ KeAcquireSpinLock(&ThreadListLock,&irql);
+
+ if (!DoneInitYet)
+ {
+ return;
+ }
+
+ DPRINT("PsDispatchThread() Current %x\n",CurrentThread);
+
+ if (CurrentThread->Tcb.ThreadState==THREAD_STATE_RUNNING)
+ {
+ CurrentThread->Tcb.ThreadState=THREAD_STATE_RUNNABLE;
+ }
+
+ for (CurrentPriority=THREAD_PRIORITY_TIME_CRITICAL;
+ CurrentPriority>=THREAD_PRIORITY_IDLE;
+ CurrentPriority--)
+ {
+ Candidate = PsScanThreadList(CurrentPriority);
+ if (Candidate == CurrentThread)
+ {
+ DPRINT("Scheduling current thread\n");
+ KeQueryTickCount(&TickCount);
+ CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
+ CurrentThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
+ KeReleaseSpinLock(&ThreadListLock,irql);
+ return;
+ }
+ if (Candidate != NULL)
+ {
+ DPRINT("Scheduling %x\n",Candidate);
+
+ Candidate->Tcb.ThreadState = THREAD_STATE_RUNNING;
+
+ KeQueryTickCount(&TickCount);
+ CurrentThread->Tcb.LastTick = GET_LARGE_INTEGER_LOW_PART(TickCount);
+
+ CurrentThread = Candidate;
+
+ HalTaskSwitch(&CurrentThread->Tcb);
+ KeReleaseSpinLock(&ThreadListLock,irql);
+ return;
+ }
+ }
+ DbgPrint("CRITICAL: No threads are runnable\n");
+ KeBugCheck(0);
+}
+
+NTSTATUS PsInitializeThread(HANDLE ProcessHandle,
+ PETHREAD* ThreadPtr,
+ PHANDLE ThreadHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ThreadAttributes)
+{
+ ULONG ThreadId;
+ ULONG ProcessId;
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ PiNrThreads++;
+
+ Thread = ObGenericCreateObject(ThreadHandle,
+ DesiredAccess,
+ ThreadAttributes,
+ PsThreadType);
+ DPRINT("Thread = %x\n",Thread);
+ Thread->Tcb.LastTick = 0;
+ Thread->Tcb.ThreadState=THREAD_STATE_SUSPENDED;
+ Thread->Tcb.BasePriority=THREAD_PRIORITY_NORMAL;
+ Thread->Tcb.CurrentPriority=THREAD_PRIORITY_NORMAL;
+ Thread->Tcb.ApcList=ExAllocatePool(NonPagedPool,sizeof(LIST_ENTRY));
+ Thread->Tcb.SuspendCount = 1;
+ if (ProcessHandle!=NULL)
+ {
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_CREATE_THREAD,
+ PsProcessType,
+ UserMode,
+ (PVOID*)&Thread->ThreadsProcess,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT("Failed at %s:%d\n",__FILE__,__LINE__);
+ return(Status);
+ }
+ }
+ else
+ {
+ Thread->ThreadsProcess=SystemProcess;
+ ObReferenceObjectByPointer(Thread->ThreadsProcess,
+ PROCESS_CREATE_THREAD,
+ PsProcessType,
+ UserMode);
+ }
+ ObReferenceObjectByPointer(Thread->ThreadsProcess,
+ PROCESS_CREATE_THREAD,
+ PsProcessType,
+ UserMode);
+ InitializeListHead(Thread->Tcb.ApcList);
+ InitializeListHead(&(Thread->IrpList));
+ Thread->Cid.UniqueThread=InterlockedIncrement(&NextThreadUniqueId);
+ ObReferenceObjectByPointer(Thread,
+ THREAD_ALL_ACCESS,
+ PsThreadType,
+ UserMode);
+ PsInsertIntoThreadList(Thread->Tcb.CurrentPriority,Thread);
+
+ *ThreadPtr = Thread;
+
+ ObDereferenceObject(Thread->ThreadsProcess);
+ return(STATUS_SUCCESS);
+}
+
+VOID PsResumeThread(PETHREAD Thread)
+{
+ DPRINT("PsResumeThread(Thread %x)\n",Thread);
+
+ Thread->Tcb.SuspendCount--;
+ DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount);
+ DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n",
+ Thread->Tcb.ThreadState,THREAD_STATE_RUNNING);
+ if (Thread->Tcb.SuspendCount <= 0 &&
+ Thread->Tcb.ThreadState != THREAD_STATE_RUNNING)
+ {
+ DPRINT("Setting thread to runnable\n");
+ Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
+ }
+ DPRINT("Finished PsResumeThread()\n");
+}
+
+VOID PsSuspendThread(PETHREAD Thread)
+{
+ DPRINT("PsSuspendThread(Thread %x)\n",Thread);
+ Thread->Tcb.SuspendCount++;
+ if (Thread->Tcb.SuspendCount > 0)
+ {
+ Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
+ if (Thread == CurrentThread)
+ {
+ PsDispatchThread();
+ }
+ }
+}
+
+void PsInitThreadManagment(void)
+/*
+ * FUNCTION: Initialize thread managment
+ */
+{
+ PETHREAD FirstThread;
+ ULONG i;
+ ANSI_STRING AnsiString;
+ HANDLE FirstThreadHandle;
+
+ KeInitializeSpinLock(&ThreadListLock);
+ for (i=0; i<NR_THREAD_PRIORITY_LEVELS; i++)
+ {
+ InitializeListHead(&PriorityListHead[i]);
+ }
+
+ PsThreadType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+
+ RtlInitAnsiString(&AnsiString,"Thread");
+ RtlAnsiStringToUnicodeString(&PsThreadType->TypeName,&AnsiString,TRUE);
+
+ PsThreadType->TotalObjects = 0;
+ PsThreadType->TotalHandles = 0;
+ PsThreadType->MaxObjects = 0;
+ PsThreadType->MaxHandles = 0;
+ PsThreadType->PagedPoolCharge = 0;
+ PsThreadType->NonpagedPoolCharge = sizeof(ETHREAD);
+ PsThreadType->Dump = NULL;
+ PsThreadType->Open = NULL;
+ PsThreadType->Close = NULL;
+ PsThreadType->Delete = NULL;
+ PsThreadType->Parse = NULL;
+ PsThreadType->Security = NULL;
+ PsThreadType->QueryName = NULL;
+ PsThreadType->OkayToClose = NULL;
+
+ PsInitializeThread(NULL,&FirstThread,&FirstThreadHandle,
+ THREAD_ALL_ACCESS,NULL);
+ HalInitFirstTask(FirstThread);
+ FirstThread->Tcb.ThreadState = THREAD_STATE_RUNNING;
+ FirstThread->Tcb.SuspendCount = 0;
+
+ DPRINT("FirstThread %x\n",FirstThread);
+
+ CurrentThread = FirstThread;
+
+ DoneInitYet = TRUE;
+}
+
+NTSTATUS NtCreateThread(PHANDLE ThreadHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ HANDLE ProcessHandle,
+ PCLIENT_ID Client,
+ PCONTEXT ThreadContext,
+ PINITIAL_TEB InitialTeb,
+ BOOLEAN CreateSuspended)
+{
+ return(ZwCreateThread(ThreadHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ProcessHandle,
+ Client,
+ ThreadContext,
+ InitialTeb,
+ CreateSuspended));
+}
+
+NTSTATUS ZwCreateThread(PHANDLE ThreadHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ HANDLE ProcessHandle,
+ PCLIENT_ID Client,
+ PCONTEXT ThreadContext,
+ PINITIAL_TEB InitialTeb,
+ BOOLEAN CreateSuspended)
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ DPRINT("ZwCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
+ ThreadHandle,ThreadContext);
+
+ Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
+ DesiredAccess,ObjectAttributes);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ HalInitTaskWithContext(Thread,ThreadContext);
+ Thread->StartAddress=NULL;
+
+ if (Client!=NULL)
+ {
+ *Client=Thread->Cid;
+ }
+
+ if (!CreateSuspended)
+ {
+ DPRINT("Not creating suspended\n");
+ PsResumeThread(Thread);
+ }
+ DPRINT("Finished PsCreateThread()\n");
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle,
+ ACCESS_MASK DesiredAccess,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ HANDLE ProcessHandle,
+ PCLIENT_ID ClientId,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext)
+/*
+ * FUNCTION: Creates a thread which executes in kernel mode
+ * ARGUMENTS:
+ * ThreadHandle (OUT) = Caller supplied storage for the returned thread
+ * handle
+ * DesiredAccess = Requested access to the thread
+ * ObjectAttributes = Object attributes (optional)
+ * ProcessHandle = Handle of process thread will run in
+ * NULL to use system process
+ * ClientId (OUT) = Caller supplied storage for the returned client id
+ * of the thread (optional)
+ * StartRoutine = Entry point for the thread
+ * StartContext = Argument supplied to the thread when it begins
+ * execution
+ * RETURNS: Success or failure status
+ */
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ DPRINT("PsCreateSystemThread(ThreadHandle %x, ProcessHandle %x)\n",
+ ThreadHandle,ProcessHandle);
+
+ Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle,
+ DesiredAccess,ObjectAttributes);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ Thread->StartAddress=StartRoutine;
+ HalInitTask(Thread,StartRoutine,StartContext);
+
+ if (ClientId!=NULL)
+ {
+ *ClientId=Thread->Cid;
+ }
+
+ PsResumeThread(Thread);
+
+ return(STATUS_SUCCESS);
+}
+
+LONG KeSetBasePriorityThread(PKTHREAD Thread, LONG Increment)
+{
+ UNIMPLEMENTED;
+}
+
+KPRIORITY KeSetPriorityThread(PKTHREAD Thread, KPRIORITY Priority)
+{
+ KPRIORITY OldPriority;
+ OldPriority = Thread->CurrentPriority;
+ Thread->CurrentPriority = Priority;
+
+ RemoveEntryList(&Thread->Entry);
+ PsInsertIntoThreadList(Thread->CurrentPriority,
+ CONTAINING_RECORD(Thread,ETHREAD,Tcb));
+
+ return(OldPriority);
+}
+
+NTSTATUS STDCALL NtAlertResumeThread(IN HANDLE ThreadHandle,
+ OUT PULONG SuspendCount)
+{
+ return(ZwAlertResumeThread(ThreadHandle,SuspendCount));
+}
+
+NTSTATUS STDCALL ZwAlertResumeThread(IN HANDLE ThreadHandle,
+ OUT PULONG SuspendCount)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtAlertThread(IN HANDLE ThreadHandle)
+{
+ return(ZwAlertThread(ThreadHandle));
+}
+
+NTSTATUS STDCALL ZwAlertThread(IN HANDLE ThreadHandle)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtGetContextThread(IN HANDLE ThreadHandle,
+ OUT PCONTEXT Context)
+{
+ return(ZwGetContextThread(ThreadHandle,Context));
+}
+
+NTSTATUS STDCALL ZwGetContextThread(IN HANDLE ThreadHandle,
+ OUT PCONTEXT Context)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ return(ZwOpenThread(ThreadHandle,
+ DesiredAccess,
+ ObjectAttributes,
+ ClientId));
+}
+
+NTSTATUS STDCALL ZwOpenThread(OUT PHANDLE ThreadHandle,
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN PCLIENT_ID ClientId)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtResumeThread(IN HANDLE ThreadHandle,
+ IN PULONG SuspendCount)
+{
+ return(ZwResumeThread(ThreadHandle,SuspendCount));
+}
+
+NTSTATUS STDCALL ZwResumeThread(IN HANDLE ThreadHandle,
+ IN PULONG SuspendCount)
+/*
+ * FUNCTION: Decrements a thread's resume count
+ * ARGUMENTS:
+ * ThreadHandle = Handle to the thread that should be resumed
+ * ResumeCount = The resulting resume count.
+ * REMARK:
+ * A thread is resumed if its suspend count is 0. This procedure maps to
+ * the win32 ResumeThread function. ( documentation about the the suspend count can be found here aswell )
+ * RETURNS: Status
+ */
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ Status = ObReferenceObjectByHandle(ThreadHandle,
+ THREAD_SUSPEND_RESUME,
+ PsThreadType,
+ UserMode,
+ (PVOID*)&Thread,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ (*SuspendCount) = InterlockedDecrement(&Thread->Tcb.SuspendCount);
+ if (Thread->Tcb.SuspendCount <= 0)
+ {
+ Thread->Tcb.ThreadState = THREAD_STATE_RUNNABLE;
+ }
+
+ ObDereferenceObject(Thread);
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS STDCALL NtSetContextThread(IN HANDLE ThreadHandle,
+ IN PCONTEXT Context)
+{
+ return(ZwSetContextThread(ThreadHandle,Context));
+}
+
+NTSTATUS STDCALL ZwSetContextThread(IN HANDLE ThreadHandle,
+ IN PCONTEXT Context)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtSuspendThread(IN HANDLE ThreadHandle,
+ IN PULONG PreviousSuspendCount)
+{
+ return(ZwSuspendThread(ThreadHandle,PreviousSuspendCount));
+}
+
+NTSTATUS STDCALL ZwSuspendThread(IN HANDLE ThreadHandle,
+ IN PULONG PreviousSuspendCount)
+/*
+ * FUNCTION: Increments a thread's suspend count
+ * ARGUMENTS:
+ * ThreadHandle = Handle to the thread that should be resumed
+ * PreviousSuspendCount = The resulting/previous suspend count.
+ * REMARK:
+ * A thread will be suspended if its suspend count is greater than 0.
+ * This procedure maps to the win32 SuspendThread function. (
+ * documentation about the the suspend count can be found here aswell )
+ * The suspend count is not increased if it is greater than
+ * MAXIMUM_SUSPEND_COUNT.
+ * RETURNS: Status
+ */
+{
+ PETHREAD Thread;
+ NTSTATUS Status;
+
+ Status = ObReferenceObjectByHandle(ThreadHandle,
+ THREAD_SUSPEND_RESUME,
+ PsThreadType,
+ UserMode,
+ (PVOID*)&Thread,
+ NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ return(Status);
+ }
+
+ (*PreviousSuspendCount) = InterlockedIncrement(&Thread->Tcb.SuspendCount);
+ if (Thread->Tcb.SuspendCount > 0)
+ {
+ Thread->Tcb.ThreadState = THREAD_STATE_SUSPENDED;
+ if (Thread == PsGetCurrentThread())
+ {
+ PsDispatchThread();
+ }
+ }
+
+ ObDereferenceObject(Thread);
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS STDCALL NtContinue(IN PCONTEXT Context, IN CINT IrqLevel)
+{
+ return(ZwContinue(Context,IrqLevel));
+}
+
+NTSTATUS STDCALL ZwContinue(IN PCONTEXT Context, IN CINT IrqLevel)
+{
+ UNIMPLEMENTED;
+}
+
+NTSTATUS STDCALL NtYieldExecution(VOID)
+{
+ return(ZwYieldExecution());
+}
+
+NTSTATUS STDCALL ZwYieldExecution(VOID)
+{
+ PsDispatchThread();
+ return(STATUS_SUCCESS);
+}
-bits 32\r
-section .text\r
-\r
-DECLARE_GLOBAL_SYMBOL InterlockedIncrement\r
- push ebp\r
- mov ebp,esp\r
-\r
- push eax\r
- push ebx\r
-\r
- mov eax,1\r
- mov ebx,[ebp+8]\r
- xadd [ebx],eax\r
-\r
- pop ebx\r
- pop eax\r
-\r
- mov esp,ebp\r
- pop ebp\r
-\r
- ret\r
- \r
- \r
-DECLARE_GLOBAL_SYMBOL InterlockedDecrement\r
- mov eax,0xffffffff\r
- mov ebx,[esp+4]\r
- xadd [ebx],eax\r
- dec eax\r
- ret\r
- \r
-DECLARE_GLOBAL_SYMBOL InterlockedExchange \r
- push ebp\r
- mov ebp,esp\r
-\r
- push eax\r
- push ebx\r
-\r
- mov eax,[ebp+12]\r
- mov ebx,[ebp+8]\r
- xchg [ebx],eax\r
- \r
- pop ebx\r
- pop eax\r
- \r
- mov esp,ebp\r
- pop ebp\r
- ret\r
-\r
-DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd\r
- mov eax,[esp+8]\r
- mov ebx,[esp+4]\r
- xadd [ebx],eax\r
- ret\r
-\r
-DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange\r
- mov eax,[esp+12]\r
- mov edx,[esp+8]\r
- mov ebx,[esp+4]\r
- cmpxchg [ebx],edx\r
- mov eax,edx\r
- ret \r
+bits 32
+section .text
+
+DECLARE_GLOBAL_SYMBOL InterlockedIncrement
+ push ebp
+ mov ebp,esp
+
+ push eax
+ push ebx
+
+ mov eax,1
+ mov ebx,[ebp+8]
+ xadd [ebx],eax
+
+ pop ebx
+ pop eax
+
+ mov esp,ebp
+ pop ebp
+
+ ret
+
+
+DECLARE_GLOBAL_SYMBOL InterlockedDecrement
+ mov eax,0xffffffff
+ mov ebx,[esp+4]
+ xadd [ebx],eax
+ dec eax
+ ret
+
+DECLARE_GLOBAL_SYMBOL InterlockedExchange
+ push ebp
+ mov ebp,esp
+
+ push eax
+ push ebx
+
+ mov eax,[ebp+12]
+ mov ebx,[ebp+8]
+ xchg [ebx],eax
+
+ pop ebx
+ pop eax
+
+ mov esp,ebp
+ pop ebp
+ ret
+
+DECLARE_GLOBAL_SYMBOL InterlockedExchangeAdd
+ mov eax,[esp+8]
+ mov ebx,[esp+4]
+ xadd [ebx],eax
+ ret
+
+DECLARE_GLOBAL_SYMBOL InterlockedCompareExchange
+ mov eax,[esp+12]
+ mov edx,[esp+8]
+ mov ebx,[esp+4]
+ cmpxchg [ebx],edx
+ mov eax,edx
+ ret
-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS kernel\r
- * FILE: ntoskrnl/rtl/unicode.c\r
- * PURPOSE: String functions\r
- * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)\r
- * UPDATE HISTORY:\r
- * Created 10/08/98\r
- */\r
-\r
-#include <base.h>\r
-#include <wstring.h>\r
-\r
-#include <ddk/ntddk.h>\r
-\r
-#include <internal/string.h>\r
-#include <internal/ke.h>\r
-#include <internal/ctype.h>\r
-\r
-#define NDEBUG\r
-#include <internal/debug.h>\r
-\r
-#define Aa_Difference ('A'-'a')\r
-\r
-PUNICODE_STRING RtlDuplicateUnicodeString(PUNICODE_STRING Dest, \r
- PUNICODE_STRING Src)\r
-{\r
- if (Dest==NULL)\r
- {\r
- Dest=ExAllocatePool(NonPagedPool,sizeof(UNICODE_STRING)); \r
- } \r
-}\r
-\r
-VOID RtlUpperString(PSTRING DestinationString, PSTRING SourceString)\r
-{\r
- UNIMPLEMENTED;\r
-}\r
-\r
-WCHAR wtoupper(WCHAR c)\r
-{\r
- if((c>='a') && (c<='z')) return c+Aa_Difference;\r
- return c;\r
-}\r
-\r
-WCHAR wtolower(WCHAR c)\r
-{\r
-// DPRINT("c %c (c-Aa_Difference) %c\n",(char)c,(char)(c-Aa_Difference));\r
- if((c>='A') && (c<='Z')) return c-Aa_Difference;\r
- return c;\r
-}\r
-\r
-ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)\r
-{\r
- return AnsiString->Length*2;\r
-}\r
-\r
-NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
- IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)\r
-{\r
- unsigned long i;\r
-\r
- if(AllocateDestinationString==TRUE) {\r
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, (SourceString->Length+1)*2);\r
- DestinationString->MaximumLength=SourceString->Length;\r
- };\r
-\r
- DestinationString->Length=SourceString->Length;\r
- memset(DestinationString->Buffer, 0, SourceString->Length*2);\r
-\r
- for (i=0; i<SourceString->Length; i++)\r
- {\r
- *DestinationString->Buffer=*SourceString->Buffer;\r
-\r
- SourceString->Buffer++;\r
- DestinationString->Buffer++;\r
- };\r
- *DestinationString->Buffer=0;\r
-\r
- SourceString->Buffer-=SourceString->Length;\r
- DestinationString->Buffer-=SourceString->Length;\r
-\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,\r
- IN PUNICODE_STRING Source)\r
-{\r
- unsigned long i;\r
-\r
- if(Destination->MaximumLength-Destination->Length-Source->Length<0)\r
- return STATUS_BUFFER_TOO_SMALL;\r
-\r
- Destination->Buffer+=Destination->Length;\r
- for(i=0; i<Source->Length; i++) {\r
- *Destination->Buffer=*Source->Buffer;\r
- Destination->Buffer++;\r
- Source->Buffer++;\r
- };\r
- *Destination->Buffer=0;\r
- Destination->Buffer-=(Destination->Length+Source->Length);\r
- Source->Buffer-=Source->Length;\r
-\r
- Destination->Length+=Source->Length;\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,\r
- IN PWSTR Source)\r
-{\r
- unsigned long i, slen=wstrlen(Source);\r
-\r
- if(Destination->MaximumLength-Destination->Length-slen<0)\r
- return STATUS_BUFFER_TOO_SMALL;\r
-\r
- Destination->Buffer+=Destination->Length;\r
- for(i=0; i<slen; i++) {\r
- *Destination->Buffer=*Source;\r
- Destination->Buffer++;\r
- Source++;\r
- };\r
- *Destination->Buffer=0;\r
- Destination->Buffer-=(Destination->Length+slen);\r
- Source-=slen;\r
-\r
- Destination->Length+=slen;\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)\r
-{\r
- *Value=simple_strtoul((const char *)String, NULL, Base);\r
-};\r
-\r
-LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)\r
-{\r
- unsigned long i;\r
- char c1, c2;\r
-\r
- if(String1->Length!=String2->Length) return String1->Length-String2->Length;\r
-\r
- for(i=0; i<String1->Length; i++) {\r
- if(CaseInsensitive==TRUE) {\r
- c1=toupper(*String1->Buffer);\r
- c2=toupper(*String2->Buffer);\r
- } else {\r
- c1=*String1->Buffer;\r
- c2=*String2->Buffer;\r
- };\r
- if(c1!=c2) {\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
- return c1-c2;\r
- };\r
- String1->Buffer++;\r
- String2->Buffer++;\r
- };\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
-\r
- return 0;\r
-};\r
-\r
-LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,\r
- BOOLEAN CaseInsensitive)\r
-{\r
- unsigned long i;\r
- WCHAR wc1, wc2;\r
-\r
- if(String1->Length!=String2->Length) return\r
- String1->Length-String2->Length;\r
-\r
- for(i=0; i<String1->Length; i++) {\r
- if(CaseInsensitive==TRUE) {\r
- wc1=wtoupper(*String1->Buffer);\r
- wc2=wtoupper(*String2->Buffer);\r
- } else {\r
- wc1=*String1->Buffer;\r
- wc2=*String2->Buffer;\r
- };\r
-\r
- if(wc1!=wc2) {\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
- return wc1-wc2;\r
- };\r
-\r
- String1->Buffer++;\r
- String2->Buffer++;\r
- };\r
-\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
-\r
- return 0;\r
-};\r
-\r
-VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)\r
-{\r
- unsigned long copylen, i;\r
-\r
- if(SourceString==NULL) {\r
- DestinationString->Length=0;\r
- } else {\r
- if(SourceString->Length<DestinationString->MaximumLength) {\r
- copylen=SourceString->Length;\r
- } else {\r
- copylen=DestinationString->MaximumLength;\r
- };\r
- for(i=0; i<copylen; i++)\r
- {\r
- *DestinationString->Buffer=*SourceString->Buffer;\r
- DestinationString->Buffer++;\r
- SourceString->Buffer++;\r
- };\r
- *DestinationString->Buffer=0;\r
- DestinationString->Buffer-=copylen;\r
- SourceString->Buffer-=copylen;\r
- };\r
-};\r
-\r
-VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
- IN PUNICODE_STRING SourceString)\r
-{\r
- unsigned long copylen, i;\r
- \r
- if(SourceString==NULL) \r
- {\r
- DestinationString->Length=0;\r
- } \r
- else \r
- {\r
- copylen = min(DestinationString->MaximumLength,\r
- SourceString->Length);\r
- for(i=0; i<copylen; i++)\r
- {\r
- *DestinationString->Buffer=*SourceString->Buffer;\r
- DestinationString->Buffer++;\r
- SourceString->Buffer++;\r
- }\r
- *DestinationString->Buffer=0;\r
- DestinationString->Buffer-=copylen;\r
- SourceString->Buffer-=copylen;\r
- }\r
-}\r
-\r
-BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)\r
-{\r
- unsigned long s1l=String1->Length;\r
- unsigned long s2l=String2->Length;\r
- unsigned long i;\r
- char c1, c2;\r
-\r
- if(s1l!=s2l) return FALSE;\r
-\r
- for(i=0; i<s1l; i++) {\r
- c1=*String1->Buffer;\r
- c2=*String2->Buffer;\r
-\r
- if(CaseInsensitive==TRUE) {\r
- c1=toupper(c1);\r
- c2=toupper(c2);\r
- };\r
-\r
- if(c1!=c2) {\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
- return FALSE;\r
- };\r
-\r
- String1->Buffer++;\r
- String2->Buffer++;\r
- };\r
-\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
-\r
- return TRUE;\r
-};\r
-\r
-BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,\r
- BOOLEAN CaseInsensitive)\r
-{\r
- unsigned long s1l=String1->Length;\r
- unsigned long s2l=String2->Length;\r
- unsigned long i;\r
- char wc1, wc2;\r
-\r
- if(s1l!=s2l) return FALSE;\r
-\r
- for(i=0; i<s1l; i++) {\r
- if(CaseInsensitive==TRUE) {\r
- wc1=wtoupper(*String1->Buffer);\r
- wc2=wtoupper(*String2->Buffer);\r
- } else {\r
- wc1=*String1->Buffer;\r
- wc2=*String2->Buffer;\r
- };\r
-\r
- if(wc1!=wc2) {\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
- return FALSE;\r
- };\r
-\r
- String1->Buffer++;\r
- String2->Buffer++;\r
- };\r
-\r
- String1->Buffer-=i;\r
- String2->Buffer-=i;\r
-\r
- return TRUE;\r
-};\r
-\r
-VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)\r
-{\r
- ExFreePool(AnsiString->Buffer);\r
-};\r
-\r
-VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)\r
-{\r
- ExFreePool(UnicodeString->Buffer);\r
-};\r
-\r
-VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,\r
- IN PCSZ SourceString)\r
-{\r
- unsigned long DestSize;\r
-\r
- if(SourceString==NULL) {\r
- DestinationString->Length=0;\r
- DestinationString->MaximumLength=0;\r
- } else {\r
- DestSize=strlen((const char *)SourceString);\r
- DestinationString->Length=DestSize;\r
- DestinationString->MaximumLength=DestSize+1;\r
- };\r
- DestinationString->Buffer=(PCHAR)SourceString;\r
-};\r
-\r
-VOID RtlInitString(IN OUT PSTRING DestinationString,\r
- IN PCSZ SourceString)\r
-{\r
- DestinationString->Length=strlen((char *)SourceString);\r
- DestinationString->MaximumLength=strlen((char *)SourceString)+1;\r
- DestinationString->Buffer=SourceString;\r
-};\r
-\r
-VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
- IN PCWSTR SourceString)\r
-{\r
- unsigned long i, DestSize;\r
-\r
- DPRINT("RtlInitUnicodeString(DestinationString %x, "\r
- "SourceString %x)\n",DestinationString,SourceString);\r
-\r
- if (SourceString==NULL)\r
- {\r
- DestinationString->Length=0;\r
- DestinationString->MaximumLength=0;\r
- DestinationString->Buffer=NULL;\r
- }\r
- else\r
- {\r
- DestSize=wstrlen((PWSTR)SourceString);\r
- DestinationString->Length=DestSize;\r
- DestinationString->MaximumLength=DestSize+1;\r
- DestinationString->Buffer=(PWSTR)SourceString;\r
- }\r
-}\r
-\r
-NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */\r
- IN OUT PUNICODE_STRING String)\r
-{\r
- char *str;\r
- unsigned long len, i;\r
-\r
- str=ExAllocatePool(NonPagedPool, 1024);\r
- if(Base==16) {\r
- sprintf(str, "%x", Value);\r
- } else\r
- if(Base==8) {\r
- sprintf(str, "%o", Value);\r
- } else\r
- if(Base==2) {\r
- sprintf(str, "%b", Value);\r
- } else {\r
- sprintf(str, "%u", Value);\r
- };\r
-\r
- len=strlen(str);\r
- if(String->MaximumLength<len) return STATUS_INVALID_PARAMETER;\r
-\r
- for(i=0; i<len; i++) {\r
- *String->Buffer=*str;\r
- String->Buffer++;\r
- str++;\r
- };\r
- *String->Buffer=0;\r
- String->Buffer-=len;\r
- String->Length=len;\r
- str-=len;\r
- ExFreePool(str);\r
-\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,\r
- IN PUNICODE_STRING SourceString,\r
- IN BOOLEAN AllocateDestinationString)\r
-{\r
- unsigned long i;\r
-\r
- if(AllocateDestinationString==TRUE) {\r
-\r
- // Causes excetion 14(0) in _Validate_Free_List\r
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);\r
- DestinationString->MaximumLength=SourceString->Length+1;\r
- };\r
-\r
- DestinationString->Length=SourceString->Length;\r
-\r
- for(i=0; i<SourceString->Length; i++) {\r
- *DestinationString->Buffer=*SourceString->Buffer;\r
- DestinationString->Buffer++;\r
- SourceString->Buffer++;\r
- };\r
- *DestinationString->Buffer=0;\r
-\r
- DestinationString->Buffer-=SourceString->Length;\r
- SourceString->Buffer-=SourceString->Length;\r
-\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,\r
- OUT PULONG Value)\r
-{\r
- char *str;\r
- unsigned long i, lenmin=0;\r
- BOOLEAN addneg=FALSE;\r
-\r
- str=ExAllocatePool(NonPagedPool, String->Length+1);\r
-\r
- for(i=0; i<String->Length; i++) {\r
- *str=*String->Buffer;\r
-\r
- if(*str=='b') { Base=2; lenmin++; } else\r
- if(*str=='o') { Base=8; lenmin++; } else\r
- if(*str=='d') { Base=10; lenmin++; } else\r
- if(*str=='x') { Base=16; lenmin++; } else\r
- if(*str=='+') { lenmin++; } else\r
- if(*str=='-') { addneg=TRUE; lenmin++; } else\r
- if((*str>'1') && (Base==2)) {\r
- String->Buffer-=i;\r
- *Value=0;\r
- return STATUS_INVALID_PARAMETER;\r
- } else\r
- if(((*str>'7') || (*str<'0')) && (Base==8)) {\r
- String->Buffer-=i;\r
- *Value=0;\r
- return STATUS_INVALID_PARAMETER;\r
- } else\r
- if(((*str>'9') || (*str<'0')) && (Base==10)) {\r
- String->Buffer-=i;\r
- *Value=0;\r
- return STATUS_INVALID_PARAMETER;\r
- } else\r
- if((((*str>'9') || (*str<'0')) ||\r
- ((toupper(*str)>'F') || (toupper(*str)<'A'))) && (Base==16))\r
- {\r
- String->Buffer-=i;\r
- *Value=0;\r
- return STATUS_INVALID_PARAMETER;\r
- } else\r
- str++;\r
-\r
- String->Buffer++;\r
- };\r
-\r
- *str=0;\r
- String->Buffer-=String->Length;\r
- str-=(String->Length-lenmin);\r
-\r
- if(addneg==TRUE) {\r
- *Value=simple_strtoul(str, NULL, Base)*-1;\r
- } else\r
- *Value=simple_strtoul(str, NULL, Base);\r
-\r
- ExFreePool(str);\r
-};\r
-\r
-NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,\r
- IN PUNICODE_STRING SourceString,\r
- IN BOOLEAN AllocateDestinationString)\r
-{\r
- unsigned long i;\r
-\r
- if(AllocateDestinationString==TRUE) {\r
- DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);\r
- DestinationString->Length=SourceString->Length;\r
- DestinationString->MaximumLength=SourceString->Length+1;\r
- };\r
-\r
- for(i=0; i<SourceString->Length; i++) {\r
- *DestinationString->Buffer=wtoupper(*SourceString->Buffer);\r
- DestinationString->Buffer++;\r
- SourceString->Buffer++;\r
- };\r
- *DestinationString->Buffer=0;\r
-\r
- DestinationString->Buffer-=SourceString->Length;\r
- SourceString->Buffer-=SourceString->Length;\r
-\r
- return STATUS_SUCCESS;\r
-};\r
-\r
-VOID RtlUpcaseString(IN OUT PSTRING DestinationString,\r
- IN PSTRING SourceString)\r
-{\r
- unsigned long i, len;\r
-\r
- if(SourceString->Length>DestinationString->MaximumLength) {\r
- len=DestinationString->MaximumLength;\r
- } else {\r
- len=SourceString->Length;\r
- };\r
-\r
- for(i=0; i<len; i++) {\r
- *DestinationString->Buffer=toupper(*SourceString->Buffer);\r
- DestinationString->Buffer++;\r
- SourceString->Buffer++;\r
- };\r
- *DestinationString->Buffer=0;\r
-\r
- DestinationString->Buffer-=len;\r
- SourceString->Buffer-=len;\r
-}\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/rtl/unicode.c
+ * PURPOSE: String functions
+ * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
+ * UPDATE HISTORY:
+ * Created 10/08/98
+ */
+
+#include <base.h>
+#include <wstring.h>
+
+#include <ddk/ntddk.h>
+
+#include <internal/string.h>
+#include <internal/ke.h>
+#include <internal/ctype.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#define Aa_Difference ('A'-'a')
+
+PUNICODE_STRING RtlDuplicateUnicodeString(PUNICODE_STRING Dest,
+ PUNICODE_STRING Src)
+{
+ if (Dest==NULL)
+ {
+ Dest=ExAllocatePool(NonPagedPool,sizeof(UNICODE_STRING));
+ }
+}
+
+VOID RtlUpperString(PSTRING DestinationString, PSTRING SourceString)
+{
+ UNIMPLEMENTED;
+}
+
+WCHAR wtoupper(WCHAR c)
+{
+ if((c>='a') && (c<='z')) return c+Aa_Difference;
+ return c;
+}
+
+WCHAR wtolower(WCHAR c)
+{
+// DPRINT("c %c (c-Aa_Difference) %c\n",(char)c,(char)(c-Aa_Difference));
+ if((c>='A') && (c<='Z')) return c-Aa_Difference;
+ return c;
+}
+
+ULONG RtlAnsiStringToUnicodeSize(IN PANSI_STRING AnsiString)
+{
+ return AnsiString->Length*2;
+}
+
+NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING DestinationString,
+ IN PANSI_STRING SourceString, IN BOOLEAN AllocateDestinationString)
+{
+ unsigned long i;
+
+ if(AllocateDestinationString==TRUE) {
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, (SourceString->Length+1)*2);
+ DestinationString->MaximumLength=SourceString->Length;
+ };
+
+ DestinationString->Length=SourceString->Length;
+ memset(DestinationString->Buffer, 0, SourceString->Length*2);
+
+ for (i=0; i<SourceString->Length; i++)
+ {
+ *DestinationString->Buffer=*SourceString->Buffer;
+
+ SourceString->Buffer++;
+ DestinationString->Buffer++;
+ };
+ *DestinationString->Buffer=0;
+
+ SourceString->Buffer-=SourceString->Length;
+ DestinationString->Buffer-=SourceString->Length;
+
+ return STATUS_SUCCESS;
+};
+
+NTSTATUS RtlAppendUnicodeStringToString(IN OUT PUNICODE_STRING Destination,
+ IN PUNICODE_STRING Source)
+{
+ unsigned long i;
+
+ if(Destination->MaximumLength-Destination->Length-Source->Length<0)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ Destination->Buffer+=Destination->Length;
+ for(i=0; i<Source->Length; i++) {
+ *Destination->Buffer=*Source->Buffer;
+ Destination->Buffer++;
+ Source->Buffer++;
+ };
+ *Destination->Buffer=0;
+ Destination->Buffer-=(Destination->Length+Source->Length);
+ Source->Buffer-=Source->Length;
+
+ Destination->Length+=Source->Length;
+ return STATUS_SUCCESS;
+};
+
+NTSTATUS RtlAppendUnicodeToString(IN OUT PUNICODE_STRING Destination,
+ IN PWSTR Source)
+{
+ unsigned long i, slen=wstrlen(Source);
+
+ if(Destination->MaximumLength-Destination->Length-slen<0)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ Destination->Buffer+=Destination->Length;
+ for(i=0; i<slen; i++) {
+ *Destination->Buffer=*Source;
+ Destination->Buffer++;
+ Source++;
+ };
+ *Destination->Buffer=0;
+ Destination->Buffer-=(Destination->Length+slen);
+ Source-=slen;
+
+ Destination->Length+=slen;
+ return STATUS_SUCCESS;
+};
+
+NTSTATUS RtlCharToInteger(IN PCSZ String, IN ULONG Base, IN OUT PULONG Value)
+{
+ *Value=simple_strtoul((const char *)String, NULL, Base);
+};
+
+LONG RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
+{
+ unsigned long i;
+ char c1, c2;
+
+ if(String1->Length!=String2->Length) return String1->Length-String2->Length;
+
+ for(i=0; i<String1->Length; i++) {
+ if(CaseInsensitive==TRUE) {
+ c1=toupper(*String1->Buffer);
+ c2=toupper(*String2->Buffer);
+ } else {
+ c1=*String1->Buffer;
+ c2=*String2->Buffer;
+ };
+ if(c1!=c2) {
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+ return c1-c2;
+ };
+ String1->Buffer++;
+ String2->Buffer++;
+ };
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+
+ return 0;
+};
+
+LONG RtlCompareUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
+ BOOLEAN CaseInsensitive)
+{
+ unsigned long i;
+ WCHAR wc1, wc2;
+
+ if(String1->Length!=String2->Length) return
+ String1->Length-String2->Length;
+
+ for(i=0; i<String1->Length; i++) {
+ if(CaseInsensitive==TRUE) {
+ wc1=wtoupper(*String1->Buffer);
+ wc2=wtoupper(*String2->Buffer);
+ } else {
+ wc1=*String1->Buffer;
+ wc2=*String2->Buffer;
+ };
+
+ if(wc1!=wc2) {
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+ return wc1-wc2;
+ };
+
+ String1->Buffer++;
+ String2->Buffer++;
+ };
+
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+
+ return 0;
+};
+
+VOID RtlCopyString(IN OUT PSTRING DestinationString, IN PSTRING SourceString)
+{
+ unsigned long copylen, i;
+
+ if(SourceString==NULL) {
+ DestinationString->Length=0;
+ } else {
+ if(SourceString->Length<DestinationString->MaximumLength) {
+ copylen=SourceString->Length;
+ } else {
+ copylen=DestinationString->MaximumLength;
+ };
+ for(i=0; i<copylen; i++)
+ {
+ *DestinationString->Buffer=*SourceString->Buffer;
+ DestinationString->Buffer++;
+ SourceString->Buffer++;
+ };
+ *DestinationString->Buffer=0;
+ DestinationString->Buffer-=copylen;
+ SourceString->Buffer-=copylen;
+ };
+};
+
+VOID RtlCopyUnicodeString(IN OUT PUNICODE_STRING DestinationString,
+ IN PUNICODE_STRING SourceString)
+{
+ unsigned long copylen, i;
+
+ if(SourceString==NULL)
+ {
+ DestinationString->Length=0;
+ }
+ else
+ {
+ copylen = min(DestinationString->MaximumLength,
+ SourceString->Length);
+ for(i=0; i<copylen; i++)
+ {
+ *DestinationString->Buffer=*SourceString->Buffer;
+ DestinationString->Buffer++;
+ SourceString->Buffer++;
+ }
+ *DestinationString->Buffer=0;
+ DestinationString->Buffer-=copylen;
+ SourceString->Buffer-=copylen;
+ }
+}
+
+BOOLEAN RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInsensitive)
+{
+ unsigned long s1l=String1->Length;
+ unsigned long s2l=String2->Length;
+ unsigned long i;
+ char c1, c2;
+
+ if(s1l!=s2l) return FALSE;
+
+ for(i=0; i<s1l; i++) {
+ c1=*String1->Buffer;
+ c2=*String2->Buffer;
+
+ if(CaseInsensitive==TRUE) {
+ c1=toupper(c1);
+ c2=toupper(c2);
+ };
+
+ if(c1!=c2) {
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+ return FALSE;
+ };
+
+ String1->Buffer++;
+ String2->Buffer++;
+ };
+
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+
+ return TRUE;
+};
+
+BOOLEAN RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2,
+ BOOLEAN CaseInsensitive)
+{
+ unsigned long s1l=String1->Length;
+ unsigned long s2l=String2->Length;
+ unsigned long i;
+ char wc1, wc2;
+
+ if(s1l!=s2l) return FALSE;
+
+ for(i=0; i<s1l; i++) {
+ if(CaseInsensitive==TRUE) {
+ wc1=wtoupper(*String1->Buffer);
+ wc2=wtoupper(*String2->Buffer);
+ } else {
+ wc1=*String1->Buffer;
+ wc2=*String2->Buffer;
+ };
+
+ if(wc1!=wc2) {
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+ return FALSE;
+ };
+
+ String1->Buffer++;
+ String2->Buffer++;
+ };
+
+ String1->Buffer-=i;
+ String2->Buffer-=i;
+
+ return TRUE;
+};
+
+VOID RtlFreeAnsiString(IN PANSI_STRING AnsiString)
+{
+ ExFreePool(AnsiString->Buffer);
+};
+
+VOID RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
+{
+ ExFreePool(UnicodeString->Buffer);
+};
+
+VOID RtlInitAnsiString(IN OUT PANSI_STRING DestinationString,
+ IN PCSZ SourceString)
+{
+ unsigned long DestSize;
+
+ if(SourceString==NULL) {
+ DestinationString->Length=0;
+ DestinationString->MaximumLength=0;
+ } else {
+ DestSize=strlen((const char *)SourceString);
+ DestinationString->Length=DestSize;
+ DestinationString->MaximumLength=DestSize+1;
+ };
+ DestinationString->Buffer=(PCHAR)SourceString;
+};
+
+VOID RtlInitString(IN OUT PSTRING DestinationString,
+ IN PCSZ SourceString)
+{
+ DestinationString->Length=strlen((char *)SourceString);
+ DestinationString->MaximumLength=strlen((char *)SourceString)+1;
+ DestinationString->Buffer=SourceString;
+};
+
+VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
+ IN PCWSTR SourceString)
+{
+ unsigned long i, DestSize;
+
+ DPRINT("RtlInitUnicodeString(DestinationString %x, "
+ "SourceString %x)\n",DestinationString,SourceString);
+
+ if (SourceString==NULL)
+ {
+ DestinationString->Length=0;
+ DestinationString->MaximumLength=0;
+ DestinationString->Buffer=NULL;
+ }
+ else
+ {
+ DestSize=wstrlen((PWSTR)SourceString);
+ DestinationString->Length=DestSize;
+ DestinationString->MaximumLength=DestSize+1;
+ DestinationString->Buffer=(PWSTR)SourceString;
+ }
+}
+
+NTSTATUS RtlIntegerToUnicodeString(IN ULONG Value, IN ULONG Base, /* optional */
+ IN OUT PUNICODE_STRING String)
+{
+ char *str;
+ unsigned long len, i;
+
+ str=ExAllocatePool(NonPagedPool, 1024);
+ if(Base==16) {
+ sprintf(str, "%x", Value);
+ } else
+ if(Base==8) {
+ sprintf(str, "%o", Value);
+ } else
+ if(Base==2) {
+ sprintf(str, "%b", Value);
+ } else {
+ sprintf(str, "%u", Value);
+ };
+
+ len=strlen(str);
+ if(String->MaximumLength<len) return STATUS_INVALID_PARAMETER;
+
+ for(i=0; i<len; i++) {
+ *String->Buffer=*str;
+ String->Buffer++;
+ str++;
+ };
+ *String->Buffer=0;
+ String->Buffer-=len;
+ String->Length=len;
+ str-=len;
+ ExFreePool(str);
+
+ return STATUS_SUCCESS;
+};
+
+NTSTATUS RtlUnicodeStringToAnsiString(IN OUT PANSI_STRING DestinationString,
+ IN PUNICODE_STRING SourceString,
+ IN BOOLEAN AllocateDestinationString)
+{
+ unsigned long i;
+
+ if(AllocateDestinationString==TRUE) {
+
+ // Causes excetion 14(0) in _Validate_Free_List
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length+1);
+ DestinationString->MaximumLength=SourceString->Length+1;
+ };
+
+ DestinationString->Length=SourceString->Length;
+
+ for(i=0; i<SourceString->Length; i++) {
+ *DestinationString->Buffer=*SourceString->Buffer;
+ DestinationString->Buffer++;
+ SourceString->Buffer++;
+ };
+ *DestinationString->Buffer=0;
+
+ DestinationString->Buffer-=SourceString->Length;
+ SourceString->Buffer-=SourceString->Length;
+
+ return STATUS_SUCCESS;
+};
+
+NTSTATUS RtlUnicodeStringToInteger(IN PUNICODE_STRING String, IN ULONG Base,
+ OUT PULONG Value)
+{
+ char *str;
+ unsigned long i, lenmin=0;
+ BOOLEAN addneg=FALSE;
+
+ str=ExAllocatePool(NonPagedPool, String->Length+1);
+
+ for(i=0; i<String->Length; i++) {
+ *str=*String->Buffer;
+
+ if(*str=='b') { Base=2; lenmin++; } else
+ if(*str=='o') { Base=8; lenmin++; } else
+ if(*str=='d') { Base=10; lenmin++; } else
+ if(*str=='x') { Base=16; lenmin++; } else
+ if(*str=='+') { lenmin++; } else
+ if(*str=='-') { addneg=TRUE; lenmin++; } else
+ if((*str>'1') && (Base==2)) {
+ String->Buffer-=i;
+ *Value=0;
+ return STATUS_INVALID_PARAMETER;
+ } else
+ if(((*str>'7') || (*str<'0')) && (Base==8)) {
+ String->Buffer-=i;
+ *Value=0;
+ return STATUS_INVALID_PARAMETER;
+ } else
+ if(((*str>'9') || (*str<'0')) && (Base==10)) {
+ String->Buffer-=i;
+ *Value=0;
+ return STATUS_INVALID_PARAMETER;
+ } else
+ if((((*str>'9') || (*str<'0')) ||
+ ((toupper(*str)>'F') || (toupper(*str)<'A'))) && (Base==16))
+ {
+ String->Buffer-=i;
+ *Value=0;
+ return STATUS_INVALID_PARAMETER;
+ } else
+ str++;
+
+ String->Buffer++;
+ };
+
+ *str=0;
+ String->Buffer-=String->Length;
+ str-=(String->Length-lenmin);
+
+ if(addneg==TRUE) {
+ *Value=simple_strtoul(str, NULL, Base)*-1;
+ } else
+ *Value=simple_strtoul(str, NULL, Base);
+
+ ExFreePool(str);
+};
+
+NTSTATUS RtlUpcaseUnicodeString(IN OUT PUNICODE_STRING DestinationString,
+ IN PUNICODE_STRING SourceString,
+ IN BOOLEAN AllocateDestinationString)
+{
+ unsigned long i;
+
+ if(AllocateDestinationString==TRUE) {
+ DestinationString->Buffer=ExAllocatePool(NonPagedPool, SourceString->Length*2+1);
+ DestinationString->Length=SourceString->Length;
+ DestinationString->MaximumLength=SourceString->Length+1;
+ };
+
+ for(i=0; i<SourceString->Length; i++) {
+ *DestinationString->Buffer=wtoupper(*SourceString->Buffer);
+ DestinationString->Buffer++;
+ SourceString->Buffer++;
+ };
+ *DestinationString->Buffer=0;
+
+ DestinationString->Buffer-=SourceString->Length;
+ SourceString->Buffer-=SourceString->Length;
+
+ return STATUS_SUCCESS;
+};
+
+VOID RtlUpcaseString(IN OUT PSTRING DestinationString,
+ IN PSTRING SourceString)
+{
+ unsigned long i, len;
+
+ if(SourceString->Length>DestinationString->MaximumLength) {
+ len=DestinationString->MaximumLength;
+ } else {
+ len=SourceString->Length;
+ };
+
+ for(i=0; i<len; i++) {
+ *DestinationString->Buffer=toupper(*SourceString->Buffer);
+ DestinationString->Buffer++;
+ SourceString->Buffer++;
+ };
+ *DestinationString->Buffer=0;
+
+ DestinationString->Buffer-=len;
+ SourceString->Buffer-=len;
+}