/*++ * @name CsrParseServerCommandLine * * The CsrParseServerCommandLine routine parses the CSRSS command-line in the * registry and performs operations for each entry found. * * @param ArgumentCount * Number of arguments on the command line. * * @param Arguments * Array of arguments. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrParseServerCommandLine(IN ULONG ArgumentCount, IN PCHAR Arguments[]) { NTSTATUS Status; PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; ULONG i, DllIndex; ANSI_STRING AnsiString; OBJECT_ATTRIBUTES ObjectAttributes; /* Set the Defaults */ CsrTotalPerProcessDataLength = 0; CsrObjectDirectory = NULL; CsrMaxApiRequestThreads = 16; /* Save our Session ID, and create a Directory for it */ SessionId = NtCurrentPeb()->SessionId; Status = CsrCreateSessionObjectDirectory(SessionId); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", Status); /* It's not fatal if the session ID isn't zero */ if (SessionId != 0) return Status; ASSERT(NT_SUCCESS(Status)); } /* Loop through every argument */ for (i = 1; i < ArgumentCount; i++) { /* Split Name and Value */ ParameterName = Arguments[i]; ParameterValue = NULL; ParameterValue = strchr(ParameterName, '='); if (ParameterValue) *ParameterValue++ = ANSI_NULL; DPRINT("Name=%s, Value=%s\n", ParameterName, ParameterValue); /* Check for Object Directory */ if (_stricmp(ParameterName, "ObjectDirectory") == 0) { /* Check if a session ID is specified */ if (SessionId != 0) { DPRINT1("Sessions not yet implemented\n"); ASSERT(SessionId); } /* Initialize the directory name */ RtlInitAnsiString(&AnsiString, ParameterValue); Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, &AnsiString, TRUE); ASSERT(NT_SUCCESS(Status) || SessionId != 0); if (!NT_SUCCESS(Status)) return Status; /* Create it */ InitializeObjectAttributes(&ObjectAttributes, &CsrDirectoryName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = NtCreateDirectoryObject(&CsrObjectDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return Status; /* Secure it */ Status = CsrSetDirectorySecurity(CsrObjectDirectory); if (!NT_SUCCESS(Status)) return Status; } else if (_stricmp(ParameterName, "SubSystemType") == 0) { /* Ignored */ } else if (_stricmp(ParameterName, "MaxRequestThreads") == 0) { Status = RtlCharToInteger(ParameterValue, 0, &CsrMaxApiRequestThreads); } else if (_stricmp(ParameterName, "RequestThreads") == 0) { /* Ignored */ Status = STATUS_SUCCESS; } else if (_stricmp(ParameterName, "ProfileControl") == 0) { /* Ignored */ } else if (_stricmp(ParameterName, "SharedSection") == 0) { /* Create the Section */ Status = CsrSrvCreateSharedSection(ParameterValue); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n", ParameterName, ParameterValue, Status); return Status; } /* Load us */ Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSRSRV_SERVERDLL_INDEX); } else if (_stricmp(ParameterName, "ServerDll") == 0) { /* Loop the command line */ EntryPoint = NULL; Status = STATUS_INVALID_PARAMETER; ServerString = ParameterValue; while (*ServerString) { /* Check for the Entry Point */ if ((*ServerString == ':') && (!EntryPoint)) { /* Found it. Add a nullchar and save it */ *ServerString++ = ANSI_NULL; EntryPoint = ServerString; } /* Check for the Dll Index */ if (*ServerString++ == ',') break; } /* Did we find something to load? */ if (!*ServerString) { DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", ParameterValue, Status); return Status; } /* Convert it to a ULONG */ Status = RtlCharToInteger(ServerString, 10, &DllIndex); /* Add a null char if it was valid */ if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; /* Load it */ if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", ParameterValue, Status); return Status; } } else if (_stricmp(ParameterName, "Windows") == 0) { /* Ignored */ // Check whether we want to start in pure GUI or pure CLI. } else { /* Invalid parameter on the command line */ Status = STATUS_INVALID_PARAMETER; } } /* Return status */ return Status; }
int _cdecl main( int argc, char *argv[] ) { BOOL fShowUsage; PCHAR s, s1; ULONG ProcessId; HANDLE Process, ThreadToResume; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Unicode; NTSTATUS Status; PRTL_EVENT_LOG EventLog; PRTL_EVENT Event; PRTL_EVENT_ID_INFO EventId; STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; PCHAR CommandLine; ULONG EventLogFlags; ULONG EventClassMask; ULONG ProcessCreateFlags; InitializeSymbolPathEnvVar(); VerboseFlag = FALSE; EventClassMask = 0xFFFFFFFF; CommandLine = NULL; ProcessId = 0xFFFFFFFF; fShowUsage = FALSE; ProcessCreateFlags = CREATE_SUSPENDED; while (--argc) { s = *++argv; if (*s == '-' || *s == '/') { while (*++s) { switch( toupper( *s ) ) { case 'M': if (--argc) { s1 = *++argv; if (isalpha( *s1 )) { EventClassMask = 0; while (*s1) { switch( toupper( *s1 ) ) { case 'H': if (isdigit( s1[1] )) { while (isdigit( *++s1 )) { switch (*s1) { case '0': EventClassMask |= RTL_EVENT_CLASS_PROCESS_HEAP ; break; case '1': EventClassMask |= RTL_EVENT_CLASS_PRIVATE_HEAP ; break; case '2': EventClassMask |= RTL_EVENT_CLASS_KERNEL_HEAP ; break; case '3': EventClassMask |= RTL_EVENT_CLASS_GDI_HEAP ; break; case '4': EventClassMask |= RTL_EVENT_CLASS_USER_HEAP ; break; case '5': EventClassMask |= RTL_EVENT_CLASS_CONSOLE_HEAP ; break; case '6': EventClassMask |= RTL_EVENT_CLASS_DESKTOP_HEAP ; break; case '7': EventClassMask |= RTL_EVENT_CLASS_CSR_SHARED_HEAP; break; default: fprintf( stderr, "RESMON: Invalid heap class digit '%c' flag.\n", *s1 ); fShowUsage = TRUE; break; } } s1 -= 1; } else { EventClassMask |= RTL_EVENT_CLASS_HEAP_ALL; } break; case 'O': EventClassMask |= RTL_EVENT_CLASS_OB; break; case 'F': EventClassMask |= RTL_EVENT_CLASS_IO; break; case 'V': EventClassMask |= RTL_EVENT_CLASS_VM; break; case 'P': EventClassMask |= RTL_EVENT_CLASS_PAGE_FAULT; break; case 'T': EventClassMask |= RTL_EVENT_CLASS_TRANSITION_FAULT; break; default: fprintf( stderr, "RESMON: Invalid event class letter '%c' flag.\n", *s1 ); fShowUsage = TRUE; break; } s1 += 1; } } else { Status = RtlCharToInteger( s1, 16, &EventClassMask ); } } else { fprintf( stderr, "RESMON: Missing process id of -%c flag.\n", *s ); fShowUsage = TRUE; } break; case 'P': if (--argc) { s1 = *++argv; ProcessId = atoi( s1 ); } else { fprintf( stderr, "RESMON: Missing process id of -%c flag.\n", *s ); fShowUsage = TRUE; } break; case 'O': EventLogFlags |= RTL_EVENT_LOG_INHERIT; break; case '2': ProcessCreateFlags |= CREATE_NEW_CONSOLE; break; case 'V': VerboseFlag = TRUE; break; case '?': case 'H': fShowUsage = TRUE; break; default: fprintf( stderr, "RESMON: Invalid flag - '%c'\n", *s ); fShowUsage = TRUE; break; } } } else if (fShowUsage) { break; } else if (CommandLine != NULL) { fShowUsage = TRUE; break; } else { CommandLine = s; } } if (fShowUsage) { fprintf( stderr, "usage: RESMON [-h] [-o] [-m EventMask] [-p ProcessId | Command]\n" ); fprintf( stderr, "where: -h - displays this help message.\n" ); fprintf( stderr, " -o - monitor all sub-processes too.\n" ); fprintf( stderr, " -m EventMask - specifies which events to monitor.\n" ); fprintf( stderr, " Default is all events. EventMask\n" ); fprintf( stderr, " consists of one or more letters\n" ); fprintf( stderr, " which stand for the following:\n" ); fprintf( stderr, " H[n] - heap events.\n" ); fprintf( stderr, " 0 - process heap.\n" ); fprintf( stderr, " 1 - private heap.\n" ); fprintf( stderr, " 2 - CSRSS heap.\n" ); fprintf( stderr, " 3 - CSR Port heap.\n" ); fprintf( stderr, " F - file events.\n" ); fprintf( stderr, " O - object events.\n" ); fprintf( stderr, " V - virtual memory events.\n" ); fprintf( stderr, " P - page faults.\n" ); fprintf( stderr, " -p ProcessId - specifies which process to monitor.\n" ); fprintf( stderr, " Default is -1 which is the Windows\n" ); fprintf( stderr, " SubSystem process.\n" ); fprintf( stderr, " Command - if -p is not specified then a command to\n" ); fprintf( stderr, " execute may be specified in quotes.\n" ); return 1; } ThreadToResume = NULL; if (CommandLine != NULL) { RtlZeroMemory( &StartupInfo, sizeof( StartupInfo ) ); StartupInfo.cb = sizeof( StartupInfo ); StartupInfo.lpReserved = NULL; StartupInfo.lpReserved2 = NULL; StartupInfo.lpDesktop = NULL; StartupInfo.lpTitle = CommandLine; StartupInfo.dwX = 0; StartupInfo.dwY = 1; StartupInfo.dwXSize = 100; StartupInfo.dwYSize = 100; StartupInfo.dwFlags = 0;//STARTF_SHELLOVERRIDE; StartupInfo.wShowWindow = SW_SHOWNORMAL; if (!CreateProcess( NULL, CommandLine, NULL, NULL, TRUE, ProcessCreateFlags, NULL, NULL, &StartupInfo, &ProcessInformation ) ) { fprintf( stderr, "RESMON: CreateProcess( %s ) failed - %lu\n", CommandLine, GetLastError() ); return 1; } Process = ProcessInformation.hProcess; ThreadToResume = ProcessInformation.hThread; ProcessId = ProcessInformation.dwProcessId; InitializeImageDebugInformation( LoadSymbolsFilter, Process, TRUE, TRUE ); } else if (ProcessId == 0xFFFFFFFF) { RtlInitUnicodeString( &Unicode, L"\\WindowsSS" ); InitializeObjectAttributes( &ObjectAttributes, &Unicode, 0, NULL, NULL ); Status = NtOpenProcess( &Process, MAXIMUM_ALLOWED, &ObjectAttributes, NULL ); if (!NT_SUCCESS( Status )) { fprintf( stderr, "OpenProcess( %wZ ) failed - %lx\n", &Unicode, Status ); return 1; } InitializeImageDebugInformation( LoadSymbolsFilter, Process, FALSE, TRUE ); } else { Process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ProcessId ); if (!Process) { fprintf( stderr, "OpenProcess( %ld ) failed - %lx\n", ProcessId, GetLastError() ); return 1; } InitializeImageDebugInformation( LoadSymbolsFilter, Process, FALSE, TRUE ); } Status = RtlCreateEventLog( Process, EventLogFlags, EventClassMask, &EventLog ); CloseHandle( Process ); if (NT_SUCCESS( Status )) { if (ThreadToResume != NULL) { printf( "Monitoring Command '%s'\n", CommandLine ); ResumeThread( ThreadToResume ); CloseHandle( ThreadToResume ); } else if (ProcessId == 0xFFFFFFFF) { printf( "Monitoring Windows SubSystem Process\n" ); } else { printf( "Monitoring Process %d\n", ProcessId ); } printf( " Events to monitor:" ); if (EventClassMask & RTL_EVENT_CLASS_HEAP_ALL) { printf( " Heap(" ); if (EventClassMask & RTL_EVENT_CLASS_PROCESS_HEAP) { printf( " Process" ); } if (EventClassMask & RTL_EVENT_CLASS_PRIVATE_HEAP) { printf( " Private" ); } if (EventClassMask & RTL_EVENT_CLASS_KERNEL_HEAP) { printf( " Kernel" ); } if (EventClassMask & RTL_EVENT_CLASS_GDI_HEAP) { printf( " GDI" ); } if (EventClassMask & RTL_EVENT_CLASS_USER_HEAP) { printf( " User" ); } if (EventClassMask & RTL_EVENT_CLASS_CONSOLE_HEAP) { printf( " Console" ); } if (EventClassMask & RTL_EVENT_CLASS_DESKTOP_HEAP) { printf( " Desktop" ); } if (EventClassMask & RTL_EVENT_CLASS_CSR_SHARED_HEAP) { printf( " CSR Shared" ); } printf( ")" ); } if (EventClassMask & RTL_EVENT_CLASS_OB) { printf( " Object" ); } if (EventClassMask & RTL_EVENT_CLASS_IO) { printf( " File I/O" ); } if (EventClassMask & RTL_EVENT_CLASS_VM) { printf( " Virtual Memory" ); } if (EventClassMask & RTL_EVENT_CLASS_PAGE_FAULT) { printf( " Page Faults" ); } if (EventClassMask & RTL_EVENT_CLASS_TRANSITION_FAULT) { printf( " Transition Page Faults" ); } printf( "\n" ); Event = (PRTL_EVENT)EventBuffer; while (TRUE) { if (EventLog->CountOfClients == 0) { break; } Status = RtlWaitForEvent( EventLog, sizeof( EventBuffer ), Event, &EventId ); if (!NT_SUCCESS( Status )) { fprintf( stderr, "RESMON: RtlWaitForEventFailed - %x\n", Status ); } if (CreateProcessEventId == NULL && !_stricmp( EventId->Name, "CreateProcess" ) ) { CreateProcessEventId = EventId; } else if (ExitProcessEventId == NULL && !_stricmp( EventId->Name, "ExitProcess" ) ) { ExitProcessEventId = EventId; } else if (LoadModuleEventId == NULL && !_stricmp( EventId->Name, "LoadModule" ) ) { LoadModuleEventId = EventId; } else if (UnloadModuleEventId == NULL && !_stricmp( EventId->Name, "UnloadModule" ) ) { UnloadModuleEventId = EventId; } else if (PageFaultEventId == NULL && !_stricmp( EventId->Name, "PageFault" ) ) { PageFaultEventId = EventId; } if (CreateProcessEventId == EventId || LoadModuleEventId == EventId ) { LoadSymbolsForEvent( Event, EventId ); DumpEvent( Event, EventId ); } else if (ExitProcessEventId == EventId) { EventLog->CountOfClients -= 1; DumpEvent( Event, EventId ); UnloadProcessForEvent( Event, EventId ); } else if (UnloadModuleEventId == EventId) { DumpEvent( Event, EventId ); UnloadSymbolsForEvent( Event, EventId ); } else { DumpEvent( Event, EventId ); } } RtlDestroyEventLog( EventLog ); } else { if (ThreadToResume != NULL) { fprintf( stderr, "RESMON: Unable (%x) to monitor Command '%s'\n", Status, CommandLine ); TerminateThread( ThreadToResume, GetLastError() ); CloseHandle( ThreadToResume ); } else { fprintf( stderr, "RESMON: Unable (%x) to monitor Process %d\n", Status, ProcessId ); } } return 0; }
int _CDECL main( int argc, char *argv[] ) { ULONG Seed; ULONG Temp; ULONG i; CHAR Str[64]; DbgPrint("Start IntegerToChar and CharToInteger Test\n"); Seed = 0x12345678; RtlIntegerToChar(Seed, 2, sizeof(Str), Str); DbgPrint("Seed = 0b%s\n", Str); RtlCharToInteger(Str, 2, &Temp); ASSERTMSG( "RtlCharToInteger(2)", (Seed == Temp) ); RtlIntegerToChar(Seed, 8, sizeof(Str), Str); DbgPrint("Seed = 0o%s\n", Str); RtlCharToInteger(Str, 8, &Temp); ASSERTMSG( "RtlCharToInteger(8)", (Seed == Temp) ); RtlIntegerToChar(Seed, 10, sizeof(Str), Str); DbgPrint("Seed = %s\n", Str); RtlCharToInteger(Str, 10, &Temp); ASSERTMSG( "RtlCharToInteger(10)", (Seed == Temp) ); RtlIntegerToChar(Seed, 16, -8, Str); Str[ 8 ] = '\0'; DbgPrint("Seed = 0x%s\n", Str); RtlCharToInteger(Str, 16, &Temp); ASSERTMSG( "RtlCharToInteger(16)", (Seed == Temp) ); DbgPrint("End IntegerToChar and CharToInteger Test\n"); DbgPrint("Start RandomTest()\n"); Seed = 0; for (i=0; i<2048; i++) { if ((i % 3) == 0) { DbgPrint("\n"); } RtlRandom(&Seed); DbgPrint("%p ", Seed); RtlIntegerToChar(Seed, 16, sizeof(Str), Str); DbgPrint("= %s ", Str); } DbgPrint("\n"); DbgPrint("End RandomTest()\n"); return TRUE; }
VOID NdisReadNetworkAddress( OUT PNDIS_STATUS Status, OUT PVOID * NetworkAddress, OUT PUINT NetworkAddressLength, IN NDIS_HANDLE ConfigurationHandle ) /*++ Routine Description: This routine is used to read the "NetworkAddress" parameter from the configuration database. It reads the value as a string separated by hyphens, then converts it to a binary array and stores the result. Arguments: Status - Returns the status of the request. NetworkAddress - Returns a pointer to the address. NetworkAddressLength - Returns the length of the address. ConfigurationHandle - Handle returned by NdisOpenConfiguration. Points to the parameter subkey. Return Value: None. --*/ { NDIS_STRING NetAddrStr = NDIS_STRING_CONST("NetworkAddress"); PNDIS_CONFIGURATION_PARAMETER ParameterValue; NTSTATUS NtStatus; UCHAR ConvertArray[3]; PWSTR CurrentReadLoc; PWSTR AddressEnd; PUCHAR CurrentWriteLoc; UINT TotalBytesRead; ULONG TempUlong; ULONG AddressLength; ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL); do { // // First read the "NetworkAddress" from the registry // NdisReadConfiguration(Status, &ParameterValue, ConfigurationHandle, &NetAddrStr, NdisParameterString); if ((*Status != NDIS_STATUS_SUCCESS) || (ParameterValue->ParameterType != NdisParameterString)) { *Status = NDIS_STATUS_FAILURE; break; } // // If there is not an address specified then exit now. // if (0 == ParameterValue->ParameterData.StringData.Length) { *Status = NDIS_STATUS_FAILURE; break; } // // Now convert the address to binary (we do this // in-place, since this allows us to use the memory // already allocated which is automatically freed // by NdisCloseConfiguration). // ConvertArray[2] = '\0'; CurrentReadLoc = (PWSTR)ParameterValue->ParameterData.StringData.Buffer; CurrentWriteLoc = (PUCHAR)CurrentReadLoc; TotalBytesRead = ParameterValue->ParameterData.StringData.Length; AddressEnd = CurrentReadLoc + (TotalBytesRead / sizeof(WCHAR)); AddressLength = 0; while ((CurrentReadLoc+2) <= AddressEnd) { // // Copy the current two-character value into ConvertArray // ConvertArray[0] = (UCHAR)(*(CurrentReadLoc++)); ConvertArray[1] = (UCHAR)(*(CurrentReadLoc++)); // // Convert it to a Ulong and update // NtStatus = RtlCharToInteger(ConvertArray, 16, &TempUlong); if (!NT_SUCCESS(NtStatus)) { *Status = NDIS_STATUS_FAILURE; break; } *(CurrentWriteLoc++) = (UCHAR)TempUlong; ++AddressLength; // // If the next character is a hyphen, skip it. // if (CurrentReadLoc < AddressEnd) { if (*CurrentReadLoc == (WCHAR)L'-') { ++CurrentReadLoc; } } } if (NtStatus != NDIS_STATUS_SUCCESS) break; *Status = STATUS_SUCCESS; *NetworkAddress = ParameterValue->ParameterData.StringData.Buffer; *NetworkAddressLength = AddressLength; if (AddressLength == 0) { *Status = NDIS_STATUS_FAILURE; } } while (FALSE); }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Parses received PIDs IOCTL from analyzer.py and adds ths PIDs in the hidden and monitored // lists. // Parameters : // IRP buffer data. // Return value : // NTSTATUS : STATUS_SUCCESS on success. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS parse_pids(PCHAR pids) { PCHAR start = NULL, current = NULL, data = NULL; ULONG len, pid; BOOLEAN first_pid = TRUE; NTSTATUS status; if(pids == NULL) return STATUS_INVALID_PARAMETER; status = RtlStringCbLengthA(pids, MAXSIZE, &len); if(!NT_SUCCESS(status)) return status; data = ExAllocatePoolWithTag(NonPagedPool, len+1, TEMP_TAG); if(data == NULL) return STATUS_NO_MEMORY; status = RtlStringCbPrintfA(data, len+1, "%s", pids); if(!NT_SUCCESS(status)) { ExFreePool(data); return status; } start = data; current = data; while(*current != 0x00) { if(*current == '_' && current!=start) { *current = 0x00; status = RtlCharToInteger(start, 10, &pid); if(NT_SUCCESS(status) && pid!=0) { if(first_pid) { startMonitoringProcess(pid); first_pid=FALSE; } else addHiddenProcess(pid); } start = current+1; } current++; } if(start != current) { status = RtlCharToInteger(start, 10, &pid); if(NT_SUCCESS(status) && pid!=0) { if(first_pid) startMonitoringProcess(pid); else addHiddenProcess(pid); } } ExFreePool(data); return STATUS_SUCCESS; }
NTSTATUS ExtractFont(UINT32 CodePage, PUCHAR FontBitField) { BOOLEAN bFoundFile = FALSE; HANDLE Handle; NTSTATUS Status; CHAR FileName[20]; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING LinkName; UNICODE_STRING SourceName; CFHEADER CabFileHeader; CFFILE CabFile; ULONG CabFileOffset = 0; LARGE_INTEGER ByteOffset; WCHAR SourceBuffer[MAX_PATH] = {L'\0'}; ULONG ReadCP; if(KeGetCurrentIrql() != PASSIVE_LEVEL) return STATUS_INVALID_DEVICE_STATE; RtlInitUnicodeString(&LinkName, L"\\SystemRoot"); InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenSymbolicLinkObject(&Handle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return(Status); SourceName.Length = 0; SourceName.MaximumLength = MAX_PATH * sizeof(WCHAR); SourceName.Buffer = SourceBuffer; Status = ZwQuerySymbolicLinkObject(Handle, &SourceName, NULL); ZwClose(Handle); Status = RtlAppendUnicodeToString(&SourceName, L"\\vgafonts.cab"); InitializeObjectAttributes(&ObjectAttributes, &SourceName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); Status = ZwCreateFile(&Handle, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); ByteOffset.LowPart = ByteOffset.HighPart = 0; if(NT_SUCCESS(Status)) { Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, &CabFileHeader, sizeof(CabFileHeader), &ByteOffset, NULL); if(NT_SUCCESS(Status)) { if(CabFileHeader.Signature == CAB_SIGNATURE) { // We have a valid CAB file! // Read the file table now and decrement the file count on every file. When it's zero, we read the complete table. ByteOffset.LowPart = CabFileHeader.FileTableOffset; while(CabFileHeader.FileCount) { Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, &CabFile, sizeof(CabFile), &ByteOffset, NULL); if(NT_SUCCESS(Status)) { ByteOffset.LowPart += sizeof(CabFile); // We assume here that the file name is max. 19 characters (+ 1 NULL character) long. // This should be enough for our purpose. Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, FileName, sizeof(FileName), &ByteOffset, NULL); if(NT_SUCCESS(Status)) { if(!bFoundFile) { Status = RtlCharToInteger(FileName, 0, &ReadCP); if (NT_SUCCESS(Status) && ReadCP == CodePage) { // We got the correct file. // Save the offset and loop through the rest of the file table to find the position, where the actual data starts. CabFileOffset = CabFile.FileOffset; bFoundFile = TRUE; } } ByteOffset.LowPart += strlen(FileName) + 1; } } CabFileHeader.FileCount--; } // 8 = Size of a CFFOLDER structure (see cabman). As we don't need the values of that structure, just increase the offset here. ByteOffset.LowPart += 8; ByteOffset.LowPart += CabFileOffset; // ByteOffset now contains the offset of the actual data, so we can read the RAW font Status = ZwReadFile(Handle, NULL, NULL, NULL, &IoStatusBlock, FontBitField, 2048, &ByteOffset, NULL); ZwClose(Handle); return STATUS_SUCCESS; } else { DPRINT1("Error: CAB signature is missing!\n"); Status = STATUS_UNSUCCESSFUL; } } else DPRINT1("Error: Cannot read from file\n"); ZwClose(Handle); return Status; } else { DPRINT1("Error: Cannot open vgafonts.cab\n"); return Status; } }
LONG VcdPmGetPortArray( VOID ) /*++ Routine Description: Use the registry enteries in HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM to simulate the Virtual Comm Device API: VCD_PM_Get_Port_Array. See VCD.ASM in the Win 3.1 DDK. Arguments: None Return Value: Port Array in LOWORD. Bit array of valid ports: Bit Set -> Port valid Bit clear -> Port invalid Bit 0 -> COM1, Bit 1 -> COM2, Bit 2 -> COM3... --*/ { HKEY hSerialCommKey; DWORD dwPortArray; DWORD dwPortNum; DWORD cbPortName; DWORD cbPortValue; CHAR szPortName[16]; CHAR szPortValue[16]; LONG iPort; LONG iStatus; dwPortArray = 0; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hSerialCommKey) == ERROR_SUCCESS){ cbPortName = sizeof(szPortName); cbPortValue = sizeof(szPortValue); for (iPort = 0; (iStatus = RegEnumValue(hSerialCommKey, iPort, szPortName, &cbPortName, NULL, NULL, szPortValue, &cbPortValue)) != ERROR_NO_MORE_ITEMS; iPort++) { if ((iStatus == ERROR_SUCCESS) && (cbPortValue > 3)) { if (NT_SUCCESS(RtlCharToInteger(szPortValue+3,10,&dwPortNum))) { dwPortArray |= (1 << (dwPortNum - 1)); } } cbPortName = sizeof(szPortName); cbPortValue = sizeof(szPortValue); } // WOW only supports 9 ports. See WU32OPENCOM in WUCOMM.C. dwPortArray &= 0x1FF; RegCloseKey(hSerialCommKey); } return(dwPortArray); }