static NTSTATUS NTAPI DiskIdentifierQueryRoutine( PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext) { PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; UNICODE_STRING NameU; if (ValueType == REG_SZ && ValueLength == 20 * sizeof(WCHAR)) { NameU.Buffer = (PWCHAR)ValueData; NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); NameU.Buffer = (PWCHAR)ValueData + 9; RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); return STATUS_SUCCESS; } return STATUS_UNSUCCESSFUL; }
VOID CliGetPreloadKeyboardLayouts(FE_KEYBOARDS* pFeKbds) { UINT i; WCHAR szPreLoadee[4]; // up to 999 preloads WCHAR lpszName[KL_NAMELENGTH]; UNICODE_STRING UnicodeString; HKL hkl; for (i = 1; i < 1000; i++) { wsprintf(szPreLoadee, L"%d", i); if ((GetPrivateProfileStringW( L"Preload", szPreLoadee, L"", // default = NULL lpszName, // output buffer KL_NAMELENGTH, L"keyboardlayout.ini") == -1 ) || (*lpszName == L'\0')) { break; } RtlInitUnicodeString(&UnicodeString, lpszName); RtlUnicodeStringToInteger(&UnicodeString, 16L, (PULONG)&hkl); RIPMSG2(RIP_VERBOSE, "PreLoaded HKL(%d): %08X\n", i, hkl); // // Set language flags. By its definition, LOWORD(hkl) is LANGID // SetFeKeyboardFlags(LOWORD(HandleToUlong(hkl)), pFeKbds); } }
/* * UserLoadKbdLayout * * Loads keyboard layout and creates KL object */ static PKL UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL) { LCID lCid; CHARSETINFO cs; PKL pKl; /* Create keyboard layout object */ pKl = UserCreateObject(gHandleTable, NULL, NULL, NULL, TYPE_KBDLAYOUT, sizeof(KL)); if (!pKl) { ERR("Failed to create object!\n"); return NULL; } pKl->hkl = hKL; pKl->spkf = UserLoadKbdFile(pwszKLID); /* Dereference keyboard layout */ UserDereferenceObject(pKl); /* If we failed, remove KL object */ if (!pKl->spkf) { ERR("UserLoadKbdFile(%wZ) failed!\n", pwszKLID); UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT); return NULL; } // Up to Language Identifiers.. RtlUnicodeStringToInteger(pwszKLID, (ULONG)16, (PULONG)&lCid); TRACE("Language Identifiers %wZ LCID 0x%x\n", pwszKLID, lCid); if (co_IntGetCharsetInfo(lCid, &cs)) { pKl->iBaseCharset = cs.ciCharset; pKl->dwFontSigs = cs.fs.fsCsb[0]; pKl->CodePage = (USHORT)cs.ciACP; TRACE("Charset %u Font Sig %lu CodePage %u\n", pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage); } else { pKl->iBaseCharset = ANSI_CHARSET; pKl->dwFontSigs = FS_LATIN1; pKl->CodePage = CP_ACP; } // Set initial system character set and font signature. if (gSystemFS == 0) { gSystemCPCharSet = pKl->iBaseCharset; gSystemFS = pKl->dwFontSigs; } return pKl; }
SHORT FASTCALL UserGetLanguageID(VOID) { HANDLE KeyHandle; OBJECT_ATTRIBUTES ObAttr; // http://support.microsoft.com/kb/324097 ULONG Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo; ULONG Size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH*sizeof(WCHAR); UNICODE_STRING Language; RtlInitUnicodeString( &Language, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language"); InitializeObjectAttributes( &ObAttr, &Language, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); if ( NT_SUCCESS(ZwOpenKey(&KeyHandle, KEY_READ, &ObAttr))) { pKeyInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_STRING); if ( pKeyInfo ) { RtlInitUnicodeString(&Language, L"Default"); if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle, &Language, KeyValuePartialInformation, pKeyInfo, Size, &Size)) ) { RtlInitUnicodeString(&Language, (PWSTR)pKeyInfo->Data); if (!NT_SUCCESS(RtlUnicodeStringToInteger(&Language, 16, &Ret))) { Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); } } ExFreePoolWithTag(pKeyInfo, TAG_STRING); } ZwClose(KeyHandle); } TRACE("Language ID = %x\n",Ret); return (SHORT) Ret; }
BOOL ResStrCmp( PUNICODE_STRING pstr1, PUNICODE_STRING pstr2) { if (pstr1->Length == 0) { /* * pstr1 is a resource ID, so just compare the values. */ if (pstr1->Buffer == pstr2->Buffer) return TRUE; } else { /* * pstr1 is a string. if pstr2 is an actual string compare the * string values; if pstr2 is not a string then pstr1 may be an * "integer string" of the form "#123456". so convert it to an * integer and compare the integers. * Before calling lstrcmp(), make sure pstr2 is an actual * string, not a resource ID. */ if (pstr2->Length != 0) { if (RtlEqualUnicodeString(pstr1, pstr2, TRUE)) return TRUE; } else if (pstr1->Buffer[0] == '#') { UNICODE_STRING strId; int id; strId.Length = pstr1->Length - sizeof(WCHAR); strId.MaximumLength = strId.Length; strId.Buffer = pstr1->Buffer + 1; RtlUnicodeStringToInteger(&strId, 10, (PULONG)&id); if (id == (int)pstr2->Buffer) return TRUE; } } return FALSE; }
UINT ParserGetInt(LPCWSTR lpKeyName, LPCWSTR lpFileName) { WCHAR Buffer[30]; UNICODE_STRING BufferW; ULONG Result; /* grab the text version of our entry */ if (!ParserGetString(lpKeyName, Buffer, _countof(Buffer), lpFileName)) return FALSE; if (!Buffer[0]) return FALSE; /* convert it to an actual integer */ RtlInitUnicodeString(&BufferW, Buffer); RtlUnicodeStringToInteger(&BufferW, 0, &Result); return Result; }
UINT GetRegIntFromID( HKEY hKey, int KeyID, UINT nDefault) { LPWSTR lpszValue; BOOL fAllocated; UNICODE_STRING Value; DWORD cbSize; BYTE Buf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 20 * sizeof(WCHAR)]; NTSTATUS Status; UINT ReturnValue; lpszValue = (LPWSTR)RtlLoadStringOrError(hModuleWin, KeyID, NULL, &fAllocated, FALSE); RtlInitUnicodeString(&Value, lpszValue); Status = NtQueryValueKey(hKey, &Value, KeyValuePartialInformation, (PKEY_VALUE_PARTIAL_INFORMATION)Buf, sizeof(Buf), &cbSize); if (NT_SUCCESS(Status)) { /* * Convert string to int. */ RtlInitUnicodeString(&Value, (LPWSTR)((PKEY_VALUE_PARTIAL_INFORMATION)Buf)->Data); RtlUnicodeStringToInteger(&Value, 10, &ReturnValue); } else { ReturnValue = nDefault; } LocalFree(lpszValue); return(ReturnValue); }
NTSTATUS TiGetProtocolNumber( PUNICODE_STRING FileName, PULONG Protocol) /* * FUNCTION: Returns the protocol number from a file name * ARGUMENTS: * FileName = Pointer to string with file name * Protocol = Pointer to buffer to put protocol number in * RETURNS: * Status of operation */ { UNICODE_STRING us; NTSTATUS Status; ULONG Value; PWSTR Name; TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName)); Name = FileName->Buffer; if (*Name++ != (WCHAR)L'\\') return STATUS_UNSUCCESSFUL; if (*Name == L'\0') return STATUS_UNSUCCESSFUL; RtlInitUnicodeString(&us, Name); Status = RtlUnicodeStringToInteger(&us, 10, &Value); if (!NT_SUCCESS(Status) || ((Value > 255))) return STATUS_UNSUCCESSFUL; *Protocol = Value; return STATUS_SUCCESS; }
BOOL CliSetSingleHotKey(PKEY_BASIC_INFORMATION pKeyInfo, HANDLE hKey) { UNICODE_STRING SubKeyName; HANDLE hKeySingleHotKey; OBJECT_ATTRIBUTES Obja; DWORD dwID = 0; UINT uVKey = 0; UINT uModifiers = 0; HKL hKL = NULL; NTSTATUS Status; SubKeyName.Buffer = (PWSTR)&(pKeyInfo->Name[0]); SubKeyName.Length = (USHORT)pKeyInfo->NameLength; SubKeyName.MaximumLength = (USHORT)pKeyInfo->NameLength; InitializeObjectAttributes(&Obja, &SubKeyName, OBJ_CASE_INSENSITIVE, hKey, NULL); Status = NtOpenKey(&hKeySingleHotKey, KEY_READ, &Obja); if (!NT_SUCCESS(Status)) { return FALSE; } RtlUnicodeStringToInteger(&SubKeyName, 16L, &dwID); uVKey = CliReadRegistryValue(hKeySingleHotKey, szRegVK); uModifiers = CliReadRegistryValue(hKeySingleHotKey, szRegMOD); hKL = (HKL)LongToHandle( CliReadRegistryValue(hKeySingleHotKey, szRegHKL) ); NtClose(hKeySingleHotKey); return CliImmSetHotKeyWorker(dwID, uModifiers, uVKey, hKL, ISHK_ADD); }
NTSTATUS NTAPI NtSetDefaultLocale(IN BOOLEAN UserProfile, IN LCID DefaultLocaleId) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; UNICODE_STRING LocaleString; HANDLE KeyHandle; ULONG ValueLength; WCHAR ValueBuffer[20]; HANDLE UserKey; NTSTATUS Status; UCHAR KeyValueBuffer[256]; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; PAGED_CODE(); /* Check if we have a profile */ if (UserProfile) { /* Open the user's key */ Status = RtlOpenCurrentUser(KEY_WRITE, &UserKey); if (!NT_SUCCESS(Status)) return(Status); /* Initialize the registry location */ RtlInitUnicodeString(&KeyName, L"Control Panel\\International"); RtlInitUnicodeString(&ValueName, L"Locale"); } else { /* Initialize the system registry location */ RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet" L"\\Control\\Nls\\Language"); RtlInitUnicodeString(&ValueName, L"Default"); UserKey = NULL; } /* Initailize the object attributes */ InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, UserKey, NULL); /* Check if we don't have a default locale yet */ if (!DefaultLocaleId) { /* Open the key for reading */ Status = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes); if (!NT_SUCCESS(Status)) { KeyHandle = NULL; goto Cleanup; } /* Query the key value */ KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer; Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, KeyValueInformation, sizeof(KeyValueBuffer), &ValueLength); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Check if this is a REG_DWORD */ if ((KeyValueInformation->Type == REG_DWORD) && (KeyValueInformation->DataLength == sizeof(ULONG))) { /* It contains the LCID as a DWORD */ DefaultLocaleId = *((ULONG*)KeyValueInformation->Data); } /* Otherwise check for a REG_SZ */ else if (KeyValueInformation->Type == REG_SZ) { /* Initialize a unicode string from the value data */ LocaleString.Buffer = (PWCHAR)KeyValueInformation->Data; LocaleString.Length = (USHORT)KeyValueInformation->DataLength; LocaleString.MaximumLength = LocaleString.Length; /* Convert the hex string to a number */ RtlUnicodeStringToInteger(&LocaleString, 16, &DefaultLocaleId); } else { Status = STATUS_UNSUCCESSFUL; } } else { /* Otherwise, open the key */ Status = ZwOpenKey(&KeyHandle, KEY_SET_VALUE, &ObjectAttributes); if (NT_SUCCESS(Status)) { /* Check if we had a profile */ if (UserProfile) { /* Fill in the buffer */ ValueLength = swprintf(ValueBuffer, L"%08lx", (ULONG)DefaultLocaleId); } else { /* Fill in the buffer */ ValueLength = swprintf(ValueBuffer, L"%04lx", (ULONG)DefaultLocaleId & 0xFFFF); } /* Set the length for the registry call */ ValueLength = (ValueLength + 1) * sizeof(WCHAR); /* Now write the actual value */ Status = ZwSetValueKey(KeyHandle, &ValueName, 0, REG_SZ, ValueBuffer, ValueLength); } } Cleanup: /* Close the locale key */ if (KeyHandle) { ObCloseHandle(KeyHandle, KernelMode); } /* Close the user key */ if (UserKey) { ObCloseHandle(UserKey, KernelMode); } /* Check for success */ if (NT_SUCCESS(Status)) { /* Check if it was for a user */ if (UserProfile) { /* Set the session wide thread locale */ MmSetSessionLocaleId(DefaultLocaleId); } else { /* Set system locale */ PsDefaultSystemLocaleId = DefaultLocaleId; } } /* Return status */ return Status; }
BOOL SetDefaultLanguage( IN PWLSESSION Session) { BOOL ret = FALSE; BOOL UserProfile; LONG rc; HKEY UserKey, hKey = NULL; LPCWSTR SubKey, ValueName; DWORD dwType, dwSize; LPWSTR Value = NULL; UNICODE_STRING ValueString; NTSTATUS Status; LCID Lcid; UserProfile = (Session && Session->UserToken); if (UserProfile && !ImpersonateLoggedOnUser(Session->UserToken)) { ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError()); return FALSE; // FIXME: ... or use the default language of the system?? // UserProfile = FALSE; } if (UserProfile) { rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &UserKey); if (rc != ERROR_SUCCESS) { TRACE("RegOpenCurrentUser() failed with error %lu\n", rc); goto cleanup; } SubKey = L"Control Panel\\International"; ValueName = L"Locale"; } else { UserKey = NULL; SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language"; ValueName = L"Default"; } rc = RegOpenKeyExW(UserKey ? UserKey : HKEY_LOCAL_MACHINE, SubKey, 0, KEY_READ, &hKey); if (UserKey) RegCloseKey(UserKey); if (rc != ERROR_SUCCESS) { TRACE("RegOpenKeyEx() failed with error %lu\n", rc); goto cleanup; } rc = RegQueryValueExW(hKey, ValueName, NULL, &dwType, NULL, &dwSize); if (rc != ERROR_SUCCESS) { TRACE("RegQueryValueEx() failed with error %lu\n", rc); goto cleanup; } else if (dwType != REG_SZ) { TRACE("Wrong type for %S\\%S registry entry (got 0x%lx, expected 0x%x)\n", SubKey, ValueName, dwType, REG_SZ); goto cleanup; } Value = HeapAlloc(GetProcessHeap(), 0, dwSize); if (!Value) { TRACE("HeapAlloc() failed\n"); goto cleanup; } rc = RegQueryValueExW(hKey, ValueName, NULL, NULL, (LPBYTE)Value, &dwSize); if (rc != ERROR_SUCCESS) { TRACE("RegQueryValueEx() failed with error %lu\n", rc); goto cleanup; } /* Convert Value to a Lcid */ ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize; ValueString.Buffer = Value; Status = RtlUnicodeStringToInteger(&ValueString, 16, (PULONG)&Lcid); if (!NT_SUCCESS(Status)) { TRACE("RtlUnicodeStringToInteger() failed with status 0x%08lx\n", Status); goto cleanup; } TRACE("%s language is 0x%08lx\n", UserProfile ? "User" : "System", Lcid); Status = NtSetDefaultLocale(UserProfile, Lcid); if (!NT_SUCCESS(Status)) { TRACE("NtSetDefaultLocale() failed with status 0x%08lx\n", Status); goto cleanup; } ret = TRUE; cleanup: if (Value) HeapFree(GetProcessHeap(), 0, Value); if (hKey) RegCloseKey(hKey); if (UserProfile) RevertToSelf(); return ret; }
VOID HandleMediaChangeEvent( UINT uidCdRom ) { /* * Local variables */ HANDLE hDevice; ULONG id; DWORD cb; DWORD dwLogicalDrives; DWORD dwDriveMask; DWORD dwDriveCount; DWORD dwRecipients; BOOL bResult; INT nCurrentTry; NTSTATUS Status; UNICODE_STRING ustrCdRom; UNICODE_STRING ustrCdRomId; UNICODE_STRING ustrAnyCdRom; UNICODE_STRING ustrNtPath; DEV_BROADCAST_VOLUME dbcvInfo; LPWSTR lpszCdRom = TEXT("\\Device\\CdRom"); WCHAR szDrive[] = TEXT("A:\\"); WCHAR szDevice[] = TEXT("\\\\.\\A:"); WCHAR wcDrive; WCHAR szCdRom[32]; WCHAR szBuff[256]; UserAssert(uidCdRom >= 0 && uidCdRom < NUM_MEDIA_EVENTS); // at most 24 cd-rom drives in system /* * Some initializations */ RtlInitUnicodeString( &ustrAnyCdRom, lpszCdRom ); wcDrive = UNICODE_NULL; /* * Form the \Device\CdRomX name based on uidCdRom */ wsprintfW( szCdRom, L"\\Device\\CdRom%d", uidCdRom ); RtlInitUnicodeString( &ustrCdRom, szCdRom ); /* * The uidCdRom parameter tells us which CD-ROM device generated the * MediaChange event. We need to map this device back to it's logical * drive letter because WM_DEVICECHANGE is based on drive letters. * * To avoid always searching all logical drives, we cache the last * associated drive letter. We still need to check this every time * we get notified because WinDisk can remap drive letters. */ if (wcDriveCache[uidCdRom]) { /* * Convert our DOS path name to a NT path name */ ustrNtPath.MaximumLength = sizeof(szBuff); ustrNtPath.Length = 0; ustrNtPath.Buffer = szBuff; bResult = GetDeviceObject(wcDriveCache[uidCdRom], &ustrNtPath); if (bResult) { /* * Check to see if this drive letter is the one that maps * to the CD-ROM drive that just notified us. */ if (RtlEqualUnicodeString(&ustrCdRom, &ustrNtPath, TRUE)) { /* * Yes, we found a match */ wcDrive = wcDriveCache[uidCdRom]; } } } if (!wcDrive) { /* * Either the cache wasn't initialized, or we had a re-mapping * of drive letters. Scan all drive letters looking for CD-ROM * devices and update the cache as we go. */ RtlZeroMemory(wcDriveCache, sizeof(wcDriveCache)); szDrive[0] = L'A'; szDevice[4] = L'A'; dwDriveCount = 26; //Max number of drive letters dwDriveMask = 1; //Max number of drive letters dwLogicalDrives = GetLogicalDrives(); while (dwDriveCount) { /* * Is this logical drive a CD-ROM? */ // // JOHNC - Remove after GetDriveType() is fixed if ((dwLogicalDrives & dwDriveMask) && GetDriveType(szDrive) == DRIVE_CDROM) { /* * For this CD-ROM drive, find it's NT path. */ ustrNtPath.MaximumLength = sizeof(szBuff); ustrNtPath.Length = 0; ustrNtPath.Buffer = szBuff; bResult = GetDeviceObject(szDrive[0], &ustrNtPath); if (bResult) { /* * Make sure the string is in the form \Device\CdRom */ if (RtlPrefixUnicodeString(&ustrAnyCdRom, &ustrNtPath, TRUE)) { /* * Now find it's id. We have a string that looks like * \Device\CdRom??? where ??? is the unit id */ RtlInitUnicodeString(&ustrCdRomId, (PWSTR)((PSTR)(ustrNtPath.Buffer)+ustrAnyCdRom.Length)); RtlUnicodeStringToInteger(&ustrCdRomId, 10, &id); UserAssert(id >= 0 && id < NUM_MEDIA_EVENTS); wcDriveCache[id] = szDrive[0]; //Initially set State to Unknown aDriveState[id] = DS_UNKNOWN; /* * If this is the device that notified us, remember its * drive letter so we can broadcase WM_DEVICECHANGE */ if (uidCdRom == id) { wcDrive = szDrive[0]; } } } } /* * Try the next drive */ szDrive[0] = szDrive[0] + 1; szDevice[4] = szDevice[4] + 1; dwDriveMask <<= 1; --dwDriveCount; } } /* * If we found a logical drive, determine the media state for the drive * and broadcast the WM_DEVICECHANGE notification. */ if (wcDrive) { /* * Get the Media status of this drive. Assume media is not * present in the case of an error. */ szDevice[4] = wcDrive; hDevice = CreateFile(szDevice, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice == INVALID_HANDLE_VALUE) { #ifdef DEBUG KdPrint((" CreateFile( '%ls' ) Failed. Error %lx\n", szDevice,GetLastError())); #endif return; } /* * Loop and check the CD-ROM to see if media is available. We need * this loop because some CD-ROM drives notify us that media has * arrived before the drive has recognized that it had new media. */ for (nCurrentTry = 0; nCurrentTry < MAX_TRIES; nCurrentTry++) { /* * See if media is present */ bResult = (DWORD)DeviceIoControl(hDevice, IOCTL_DISK_CHECK_VERIFY, NULL, 0, NULL, 0, &cb, NULL); if (bResult) { /* * Media is present, change the state to Inserted. */ aDriveState[uidCdRom] = DS_INSERTED; break; } /* * Media wasn't present, so we need to look at GetLastError() to see * if DeviceIoControl() failed. If so we may want to try again. */ if (GetLastError() == ERROR_NOT_READY) { Sleep(500); // 1/2 second /* * We only want to retry if we the prev State was UNKNOWN or * EJECTED. If the previous State was INSERTED it means that * this event is the removal event */ if(aDriveState[uidCdRom]== DS_UNKNOWN || aDriveState[uidCdRom] == DS_EJECTED) { continue; } } /* * Call failed. Assume worst case and say the media has been removed. */ aDriveState[uidCdRom] = DS_EJECTED; break; } /* * Close the handle to the CD-ROM device */ CloseHandle(hDevice); /* * Initialize the structures used for BroadcastSystemMessage */ dbcvInfo.dbcv_size = sizeof(dbcvInfo); dbcvInfo.dbcv_devicetype = DBT_DEVTYP_VOLUME; dbcvInfo.dbcv_reserved = 0; dbcvInfo.dbcv_flags = DBTF_MEDIA; dbcvInfo.dbcv_unitmask = (1 << (wcDrive - L'A')); dwRecipients = BSM_ALLCOMPONENTS | BSM_ALLDESKTOPS; /* * Temporarily we must assign this thread to a desktop so we can * call USER's BroascastSystemMessage() routine. We call the * private SetThreadDesktopToDefault() to assign ourselves to the * desktop that is currently receiving input. */ Status = NtUserSetInformationThread(NtCurrentThread(), UserThreadUseActiveDesktop, NULL, 0); if (NT_SUCCESS(Status)) { /* * Broadcast the message */ BroadcastSystemMessage(BSF_FORCEIFHUNG, &dwRecipients, WM_DEVICECHANGE, // HACK: need to or 0x8000 in wParam // because this is a flag to let // BSM know that lParam is a pointer // to a data structure. 0x8000 | ((bResult) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE), (LPARAM)&dbcvInfo); #ifdef DEBUG KdPrint((" Message Broadcast for '%lc:'\n", wcDrive)); #endif /* * Set our thread's desktop back to NULL. This will decrement * the desktop's reference count. */ hDevice = NULL; NtUserSetInformationThread(NtCurrentThread(), UserThreadUseDesktop, &hDevice, // hDevice = NULL sizeof(HANDLE)); } } }
BOOLEAN RosSymCreateFromMem(PVOID ImageStart, ULONG_PTR ImageSize, PROSSYM_INFO *RosSymInfo) { ANSI_STRING AnsiNameString = { }; PIMAGE_DOS_HEADER DosHeader; PIMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER SectionHeaders; ULONG SectionIndex; unsigned SymbolTable, NumSymbols; /* Check if MZ header is valid */ DosHeader = (PIMAGE_DOS_HEADER) ImageStart; if (ImageSize < sizeof(IMAGE_DOS_HEADER) || ! ROSSYM_IS_VALID_DOS_HEADER(DosHeader)) { DPRINT1("Image doesn't have a valid DOS header\n"); return FALSE; } /* Locate NT header */ NtHeaders = (PIMAGE_NT_HEADERS)((char *) ImageStart + DosHeader->e_lfanew); if (ImageSize < DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) || ! ROSSYM_IS_VALID_NT_HEADERS(NtHeaders)) { DPRINT1("Image doesn't have a valid PE header\n"); return FALSE; } SymbolTable = NtHeaders->FileHeader.PointerToSymbolTable; NumSymbols = NtHeaders->FileHeader.NumberOfSymbols; /* Search for the section header */ ULONG SectionHeaderSize = NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER); SectionHeaders = RosSymAllocMem(SectionHeaderSize); RtlCopyMemory(SectionHeaders, IMAGE_FIRST_SECTION(NtHeaders), SectionHeaderSize); // Convert names to ANSI_STRINGs for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++) { if (SectionHeaders[SectionIndex].Name[0] != '/') { AnsiNameString.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME); RtlCopyMemory(AnsiNameString.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME); AnsiNameString.MaximumLength = IMAGE_SIZEOF_SHORT_NAME; AnsiNameString.Length = GetStrnlen(AnsiNameString.Buffer, IMAGE_SIZEOF_SHORT_NAME); } else { UNICODE_STRING intConv; NTSTATUS Status; ULONG StringOffset; if (!RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1)) goto freeall; Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset); RtlFreeUnicodeString(&intConv); if (!NT_SUCCESS(Status)) goto freeall; ULONG VirtualOffset = pefindrva(SectionHeaders, NtHeaders->FileHeader.NumberOfSections, SymbolTable+(NumSymbols*SYMBOL_SIZE)+StringOffset); if (!VirtualOffset) goto freeall; AnsiNameString.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE); if (!AnsiNameString.Buffer) goto freeall; PCHAR StringTarget = ((PCHAR)ImageStart)+VirtualOffset; PCHAR EndOfImage = ((PCHAR)ImageStart) + NtHeaders->OptionalHeader.SizeOfImage; if (StringTarget >= EndOfImage) goto freeall; ULONG PossibleStringLength = EndOfImage - StringTarget; if (PossibleStringLength > MAXIMUM_DWARF_NAME_SIZE) PossibleStringLength = MAXIMUM_DWARF_NAME_SIZE; RtlCopyMemory(AnsiNameString.Buffer, StringTarget, PossibleStringLength); AnsiNameString.Length = strlen(AnsiNameString.Buffer); AnsiNameString.MaximumLength = MAXIMUM_DWARF_NAME_SIZE; } memcpy (&SectionHeaders[SectionIndex], &AnsiNameString, sizeof(AnsiNameString)); } Pe *pe = RosSymAllocMem(sizeof(*pe)); pe->fd = ImageStart; pe->e2 = peget2; pe->e4 = peget4; pe->e8 = peget8; pe->loadbase = (ULONG)ImageStart; pe->imagebase = NtHeaders->OptionalHeader.ImageBase; pe->imagesize = NtHeaders->OptionalHeader.SizeOfImage; pe->nsections = NtHeaders->FileHeader.NumberOfSections; pe->sect = SectionHeaders; pe->nsymbols = NtHeaders->FileHeader.NumberOfSymbols; pe->symtab = malloc(pe->nsymbols * sizeof(CoffSymbol)); PSYMENT SymbolData = (PSYMENT) (((PCHAR)ImageStart) + pefindrva (pe->sect, pe->nsections, NtHeaders->FileHeader.PointerToSymbolTable)); int i, j; for (i = 0, j = 0; i < pe->nsymbols; i++) { if ((SymbolData[i].e_scnum < 1) || (SymbolData[i].e_sclass != C_EXT && SymbolData[i].e_sclass != C_STAT)) continue; int section = SymbolData[i].e_scnum - 1; if (SymbolData[i].e.e.e_zeroes) { pe->symtab[j].name = malloc(sizeof(SymbolData[i].e.e_name)+1); strcpy(pe->symtab[j].name, SymbolData[i].e.e_name); } else { PCHAR SymbolName = ((PCHAR)ImageStart) + pefindrva (pe->sect, pe->nsections, NtHeaders->FileHeader.PointerToSymbolTable + (NtHeaders->FileHeader.NumberOfSymbols * 18) + SymbolData[i].e.e.e_offset); pe->symtab[j].name = malloc(strlen(SymbolName)+1); strcpy(pe->symtab[j].name, SymbolName); } if (pe->symtab[j].name[0] == '.') { free(pe->symtab[j].name); continue; } pe->symtab[j].address = pe->sect[section].VirtualAddress + SymbolData[i].e_value; j++; } pe->nsymbols = j; pe->loadsection = loadmemsection; *RosSymInfo = dwarfopen(pe); return !!*RosSymInfo; freeall: if (AnsiNameString.Buffer) RosSymFreeMem(AnsiNameString.Buffer); for (SectionIndex = 0; SectionIndex < NtHeaders->FileHeader.NumberOfSections; SectionIndex++) RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex])); RosSymFreeMem(SectionHeaders); return FALSE; }
VOID NlsUpdateCacheInfo() { LCID Locale; /* locale id */ UNICODE_STRING ObKeyName; /* key name */ LPWSTR pTmp; /* tmp string pointer */ int ctr; /* loop counter */ ULONG ResultLength; /* result length */ ULONG rc = 0L; /* return code */ BYTE KeyValuePart[MAX_KEY_VALUE_PARTINFO]; PKEY_VALUE_PARTIAL_INFORMATION pValuePart; /* * Get the cache mutant. */ NtWaitForSingleObject( hNlsCacheMutant, FALSE, NULL ); /* * Update the cache information. */ pTmp = (LPWSTR)pNlsRegUserInfo; pValuePart = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValuePart; for (ctr = 0; ctr < NumCPanelRegValues; ctr++) { RtlInitUnicodeString( &ObKeyName, pCPanelRegValues[ctr] ); rc = NtQueryValueKey( hCPanelIntlKeyRead, &ObKeyName, KeyValuePartialInformation, pValuePart, MAX_KEY_VALUE_PARTINFO, &ResultLength ); if (NT_SUCCESS( rc )) { ((LPBYTE)pValuePart)[ResultLength] = UNICODE_NULL; wcscpy(pTmp, (LPWSTR)(pValuePart->Data)); } else { *pTmp = NLS_INVALID_INFO_CHAR; *(pTmp + 1) = UNICODE_NULL; } /* * Increment pointer to cache structure. */ pTmp += MAX_REG_VAL_SIZE; } /* * Convert the user locale id string to a dword value and store * it in the cache. */ pNlsRegUserInfo->UserLocaleId = (LCID)0; if ((pNlsRegUserInfo->sLocale)[0] != NLS_INVALID_INFO_CHAR) { RtlInitUnicodeString( &ObKeyName, pNlsRegUserInfo->sLocale ); if (NT_SUCCESS(RtlUnicodeStringToInteger( &ObKeyName, 16, &Locale ))) { pNlsRegUserInfo->UserLocaleId = Locale; } } /* * Make sure the user locale id was found. Otherwise, set it to * the system locale. */ if (pNlsRegUserInfo->UserLocaleId == 0) { NtQueryDefaultLocale( FALSE, &(pNlsRegUserInfo->UserLocaleId) ); } /* * Set the cache to be valid. */ pNlsRegUserInfo->fCacheValid = TRUE; /* * Release the cache mutant. */ NtReleaseMutant( hNlsCacheMutant, NULL ); }
static UINT FASTCALL IntQueryCaretBlinkRate(VOID) { UNICODE_STRING KeyName = RTL_CONSTANT_STRING(CARET_REGKEY); UNICODE_STRING ValueName = RTL_CONSTANT_STRING(CARET_VALUENAME); NTSTATUS Status; HANDLE KeyHandle = NULL; OBJECT_ATTRIBUTES KeyAttributes; PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo; ULONG Length = 0; ULONG ResLength = 0; ULONG Val = 0; InitializeObjectAttributes(&KeyAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes); if(!NT_SUCCESS(Status)) { return 0; } Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, 0, 0, &ResLength); if((Status != STATUS_BUFFER_TOO_SMALL)) { NtClose(KeyHandle); return 0; } ResLength += sizeof(KEY_VALUE_PARTIAL_INFORMATION); KeyValuePartialInfo = ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING); Length = ResLength; if(!KeyValuePartialInfo) { NtClose(KeyHandle); return 0; } Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, (PVOID)KeyValuePartialInfo, Length, &ResLength); if(!NT_SUCCESS(Status) || (KeyValuePartialInfo->Type != REG_SZ)) { NtClose(KeyHandle); ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING); return 0; } ValueName.Length = KeyValuePartialInfo->DataLength; ValueName.MaximumLength = KeyValuePartialInfo->DataLength; ValueName.Buffer = (PWSTR)KeyValuePartialInfo->Data; Status = RtlUnicodeStringToInteger(&ValueName, 0, &Val); if(!NT_SUCCESS(Status)) { Val = 0; } ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING); NtClose(KeyHandle); return (UINT)Val; }
NTSTATUS NTAPI SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken) { NTSTATUS Status; ULONG MinSize = 0, MaxSize = 0; BOOLEAN SystemManaged = FALSE, ZeroSize = TRUE; PSMP_PAGEFILE_DESCRIPTOR Descriptor, ListDescriptor; ULONG i; WCHAR c; PLIST_ENTRY NextEntry; UNICODE_STRING PageFileName, Arguments, SecondArgument; /* Make sure we don't have too many */ if (SmpNumberOfPagingFiles >= 16) { DPRINT1("SMSS:PFILE: Too many paging files specified - %lu\n", SmpNumberOfPagingFiles); return STATUS_TOO_MANY_PAGING_FILES; } /* Parse the specified and get the name and arguments out of it */ DPRINT("SMSS:PFILE: Paging file specifier `%wZ' \n", PageFileToken); Status = SmpParseCommandLine(PageFileToken, NULL, &PageFileName, NULL, &Arguments); if (!NT_SUCCESS(Status)) { /* Fail */ DPRINT1("SMSS:PFILE: SmpParseCommandLine( %wZ ) failed - Status == %lx\n", PageFileToken, Status); return Status; } /* Set the variable to let everyone know we have a pagefile token */ SmpRegistrySpecifierPresent = TRUE; /* Parse the arguments, if any */ if (Arguments.Buffer) { /* Parse the pagefile size */ for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++) { /* Check if it's zero */ c = Arguments.Buffer[i]; if ((c != L' ') && (c != L'\t') && (c != L'0')) { /* It isn't, break out */ ZeroSize = FALSE; break; } } } /* Was a pagefile not specified, or was it specified with no size? */ if (!(Arguments.Buffer) || (ZeroSize)) { /* In this case, the system will manage its size */ SystemManaged = TRUE; } else { /* We do have a size, so convert the arguments into a number */ Status = RtlUnicodeStringToInteger(&Arguments, 0, &MinSize); if (!NT_SUCCESS(Status)) { /* Fail */ RtlFreeUnicodeString(&PageFileName); RtlFreeUnicodeString(&Arguments); return Status; } /* Now advance to the next argument */ for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++) { /* Found a space -- second argument must start here */ if (Arguments.Buffer[i] == L' ') { /* Use the rest of the arguments as a maximum size */ SecondArgument.Buffer = &Arguments.Buffer[i]; SecondArgument.Length = (USHORT)(Arguments.Length - i * sizeof(WCHAR)); SecondArgument.MaximumLength = (USHORT)(Arguments.MaximumLength - i * sizeof(WCHAR)); Status = RtlUnicodeStringToInteger(&SecondArgument, 0, &MaxSize); if (!NT_SUCCESS(Status)) { /* Fail */ RtlFreeUnicodeString(&PageFileName); RtlFreeUnicodeString(&Arguments); return Status; } break; } } } /* We are done parsing arguments */ RtlFreeUnicodeString(&Arguments); /* Now we can allocate our descriptor */ Descriptor = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SMP_PAGEFILE_DESCRIPTOR)); if (!Descriptor) { /* Fail if we couldn't */ RtlFreeUnicodeString(&PageFileName); return STATUS_NO_MEMORY; } /* Capture all our data into the descriptor */ Descriptor->Token = *PageFileToken; Descriptor->Name = PageFileName; Descriptor->MinSize.QuadPart = MinSize * MEGABYTE; Descriptor->MaxSize.QuadPart = MaxSize * MEGABYTE; if (SystemManaged) Descriptor->Flags |= SMP_PAGEFILE_SYSTEM_MANAGED; Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = RtlUpcaseUnicodeChar(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET]); if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?') { Descriptor->Flags |= SMP_PAGEFILE_ON_ANY_DRIVE; } /* Now loop the existing descriptors */ NextEntry = SmpPagingFileDescriptorList.Flink; do { /* Are there none, or have we looped back to the beginning? */ if (NextEntry == &SmpPagingFileDescriptorList) { /* This means no duplicates exist, so insert our descriptor! */ InsertTailList(&SmpPagingFileDescriptorList, &Descriptor->Entry); SmpNumberOfPagingFiles++; DPRINT("SMSS:PFILE: Created descriptor for `%wZ' (`%wZ') \n", PageFileToken, &Descriptor->Name); return STATUS_SUCCESS; } /* Keep going until we find a duplicate, unless we are in "any" mode */ ListDescriptor = CONTAINING_RECORD(NextEntry, SMP_PAGEFILE_DESCRIPTOR, Entry); NextEntry = NextEntry->Flink; } while (!(ListDescriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE) || !(Descriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE)); /* We found a duplicate, so skip this descriptor/pagefile and fail */ DPRINT1("SMSS:PFILE: Skipping duplicate specifier `%wZ' \n", PageFileToken); RtlFreeUnicodeString(&PageFileName); RtlFreeHeap(RtlGetProcessHeap(), 0, Descriptor); return STATUS_INVALID_PARAMETER; }
BOOLEAN IopInitializeDeviceInstanceKey( IN HANDLE KeyHandle, IN PUNICODE_STRING KeyName, IN OUT PVOID WorkName ) /*++ Routine Description: This routine is a callback function for IopApplyFunctionToSubKeys. It is called for each subkey under HKLM\System\Enum\BusKey\DeviceKey. Arguments: KeyHandle - Supplies a handle to this key. KeyName - Supplies the name of this key. WorkName - points to the unicodestring which describes the path up to this key. Returns: TRUE to continue the enumeration. FALSE to abort it. --*/ { UNICODE_STRING unicodeName, serviceName; PKEY_VALUE_FULL_INFORMATION keyValueInformation; NTSTATUS status; BOOLEAN duplicate = FALSE; ULONG foundAtEnum, deviceFlags, instance, tmpValue1, tmpValue2; USHORT length; PUNICODE_STRING pUnicode; // // Get the "Problem" value entry to determine what we need to do with // the device instance key. // deviceFlags = 0; status = IopGetRegistryValue ( KeyHandle, REGSTR_VALUE_PROBLEM, &keyValueInformation ); if (NT_SUCCESS(status)) { if ((keyValueInformation->Type == REG_DWORD) && (keyValueInformation->DataLength >= sizeof(ULONG))) { deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); } ExFreePool(keyValueInformation); } if (deviceFlags == CM_PROB_MOVED) { // // If the device instance was moved, we simply delete the key. // The key will be deleted once the caller close the open handle. // NtDeleteKey(KeyHandle); return TRUE; } // // The device instance key exists. We need to propagate the ConfigFlag // to problem and StatusFlags // deviceFlags = 0; status = IopGetRegistryValue(KeyHandle, REGSTR_VALUE_CONFIG_FLAGS, &keyValueInformation); if (NT_SUCCESS(status)) { if ((keyValueInformation->Type == REG_DWORD) && (keyValueInformation->DataLength >= sizeof(ULONG))) { deviceFlags = *(PULONG)KEY_VALUE_DATA(keyValueInformation); } ExFreePool(keyValueInformation); } if (deviceFlags & CONFIGFLAG_REINSTALL) { tmpValue1 = CM_PROB_REINSTALL; // Problem tmpValue2 = DN_HAS_PROBLEM; // StatusFlags } else { tmpValue1 = tmpValue2 = 0; } PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_PROBLEM); NtSetValueKey(KeyHandle, &unicodeName, TITLE_INDEX_VALUE, REG_DWORD, &tmpValue1, sizeof(tmpValue1) ); PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_STATUSFLAGS); NtSetValueKey(KeyHandle, &unicodeName, TITLE_INDEX_VALUE, REG_DWORD, &tmpValue2, sizeof(tmpValue2) ); // // Get the "DuplicateOf" value entry to determine if the device instance // should be registered. If the device instance is duplicate, We don't // add it to its service key's enum branch. // status = IopGetRegistryValue ( KeyHandle, REGSTR_VALUE_DUPLICATEOF, &keyValueInformation ); if (NT_SUCCESS(status)) { if ((keyValueInformation->Type == REG_SZ) && (keyValueInformation->DataLength > 0)) { duplicate = TRUE; } ExFreePool(keyValueInformation); } if (!duplicate) { // // Combine WorkName and KeyName to form device instance path // and register this device instance by // constructing new value entry for ServiceKeyName\Enum key. // i.e., <Number> = <PathToSystemEnumBranch> // pUnicode = (PUNICODE_STRING)WorkName; length = pUnicode->Length; // Save WorkName if (pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR) { pUnicode->Buffer[pUnicode->Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR; pUnicode->Length += 2; } RtlAppendStringToString((PSTRING)pUnicode, (PSTRING)KeyName); PpDeviceRegistration(pUnicode, TRUE); pUnicode->Length = length; // Restore WorkName } // // Get the "Service=" value entry from KeyHandle // keyValueInformation = NULL; serviceName.Length = 0; status = IopGetRegistryValue ( KeyHandle, REGSTR_VALUE_SERVICE, &keyValueInformation ); if (NT_SUCCESS(status)) { // // Append the new instance to its corresponding // Service\Name\Enum. // if ((keyValueInformation->Type == REG_SZ) && (keyValueInformation->DataLength != 0)) { // // Set up ServiceKeyName unicode string // IopRegistryDataToUnicodeString( &serviceName, (PWSTR)KEY_VALUE_DATA(keyValueInformation), keyValueInformation->DataLength ); } // // Do not Free keyValueInformation // } // // The Pnp mgr set FoundAtEnum to 0 for everything under system\ccs\enum. // For the stuff under Root we need to set them to 1 except if their // CsConfigFlags was set to CSCONFIGFLAG_DO_NOT_CREATE. // foundAtEnum = 1; status = RtlUnicodeStringToInteger(KeyName, 10, &instance); if (NT_SUCCESS(status)) { if (serviceName.Length != 0) { status = IopGetDeviceInstanceCsConfigFlags( &serviceName, instance, &deviceFlags ); if (NT_SUCCESS(status) && (deviceFlags & CSCONFIGFLAG_DO_NOT_CREATE)) { foundAtEnum = 0; } } } if (keyValueInformation) { ExFreePool(keyValueInformation); } PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_FOUNDATENUM); NtSetValueKey(KeyHandle, &unicodeName, TITLE_INDEX_VALUE, REG_DWORD, &foundAtEnum, sizeof(foundAtEnum) ); // // Clean up "NtLogicalDevicePaths=" and "NtPhysicalDevicePaths=" of this key // PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NT_PHYSICAL_DEVICE_PATHS); NtDeleteValueKey(KeyHandle, &unicodeName); PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_NT_LOGICAL_DEVICE_PATHS); NtDeleteValueKey(KeyHandle, &unicodeName); return TRUE; }
// handles operations that must be performed when an application requests access to a device. VOID vJoy_EvtDeviceFileCreate( __in WDFDEVICE Device, __in WDFREQUEST Request, __in WDFFILEOBJECT FileObject ) { WDFFILEOBJECT FileObj; PCUNICODE_STRING pName; UNICODE_STRING TmpUstr; NTSTATUS status = STATUS_SUCCESS; int id=0; WCHAR RefStr[100]; PFILEOBJECT_EXTENSION pExtension=NULL; PDEVICE_EXTENSION pDevContext = NULL; PRPDO_DEVICE_DATA pPdoData=NULL; size_t len; DWORD_PTR ProcessId; PAGED_CODE (); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "Entered vJoy_EvtDeviceFileCreate\n"); // Get file object then get its filename FileObj = WdfRequestGetFileObject(Request); if (!FileObj) goto going_out; pName = WdfFileObjectGetFileName(FileObj); if (!pName) goto going_out; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate: File name=%wZ\n", pName); // Extract id from interface number status = RtlStringCchLengthW(VJOY_INTERFACE, 100, &len); if (!NT_SUCCESS(status)) goto going_out; status = RtlStringCchCopyNW(RefStr, 100, pName->Buffer+len+1,4); // Copy the numeric part of the string (000) if (!NT_SUCCESS(status)) goto going_out; RtlInitUnicodeString(&TmpUstr, RefStr); // Convert "000" to UNICODE_STRING status = RtlUnicodeStringToInteger(&TmpUstr, 10, &id); // Convert "000" to integer (0) if (!NT_SUCCESS(status)) goto going_out; if (id>0) { // Verify that this interface has a corresponding device TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate: ID=%d\n", id); pPdoData = PdoGetData(Device); pDevContext = GetDeviceContext(pPdoData->hParentDevice); if (!pDevContext) goto going_out; if (!pDevContext->positions[id - 1]) goto going_out; // Get the file object context space // Test that this interface is not in use // and store there the parent (Raw PDO) context pExtension = GetFileObjectContext(FileObject); if (!pExtension) goto going_out; pExtension->pParentRawDeviceContext = pPdoData; if (pPdoData->UsedInterfacesMask & (1 << (id - 1))) { WdfRequestComplete(Request, STATUS_ACCESS_DENIED); ProcessId = (DWORD_PTR)PsGetCurrentProcessId(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate: PID=%d Failed (Access Denied)\n", ProcessId); return; } ///// This is a successful file creation - Now record the file details // vJoy Device ID else pPdoData->UsedInterfacesMask |= 1 << (id - 1); // Put id in file object context space pExtension->id = id; // Update // Get the id of the calling process ProcessId = (DWORD_PTR)PsGetCurrentProcessId(); pExtension->CallingProcessId = (DWORD)(ProcessId & 0xFFFFFFFF); TraceEvents(TRACE_LEVEL_WARNING, DBG_INIT, "vJoy_EvtDeviceFileCreate: PID=%d\n", pExtension->CallingProcessId); // Put the file object in the FDO extension pDevContext->DeviceFileObject[id - 1] = FileObject; // Activate FFB Queues FfbActiveSet(TRUE, id, pDevContext); WdfRequestComplete(Request, status); return; } // if (id>0) // Case of General purpose and non device-specific Interface else // if (id<1) { TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate(2nd case): ID=%d\n", id); #if 0 pPdoData = PdoGetData(Device); pDevContext = GetDeviceContext(pPdoData->hParentDevice); if (!pDevContext) goto going_out; TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate(2nd case): Completing Request\n"); #endif // 0 WdfRequestComplete(Request, status); return; }; // if (id<1) going_out: ProcessId = (DWORD_PTR)PsGetCurrentProcessId(); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "vJoy_EvtDeviceFileCreate: PID=%d Failed (Invalid Handle)\n", ProcessId); WdfRequestComplete(Request, STATUS_INVALID_HANDLE); }
BOOL SetDefaultLanguage( IN BOOL UserProfile) { HKEY BaseKey; LPCWSTR SubKey; LPCWSTR ValueName; LONG rc; HKEY hKey = NULL; DWORD dwType, dwSize; LPWSTR Value = NULL; UNICODE_STRING ValueString; NTSTATUS Status; LCID Lcid; BOOL ret = FALSE; if (UserProfile) { BaseKey = HKEY_CURRENT_USER; SubKey = L"Control Panel\\International"; ValueName = L"Locale"; } else { BaseKey = HKEY_LOCAL_MACHINE; SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language"; ValueName = L"Default"; } rc = RegOpenKeyExW( BaseKey, SubKey, 0, KEY_READ, &hKey); if (rc != ERROR_SUCCESS) { TRACE("RegOpenKeyEx() failed with error %lu\n", rc); goto cleanup; } rc = RegQueryValueExW( hKey, ValueName, NULL, &dwType, NULL, &dwSize); if (rc != ERROR_SUCCESS) { TRACE("RegQueryValueEx() failed with error %lu\n", rc); goto cleanup; } else if (dwType != REG_SZ) { TRACE("Wrong type for %S\\%S registry entry (got 0x%lx, expected 0x%x)\n", SubKey, ValueName, dwType, REG_SZ); goto cleanup; } Value = HeapAlloc(GetProcessHeap(), 0, dwSize); if (!Value) { TRACE("HeapAlloc() failed\n"); goto cleanup; } rc = RegQueryValueExW( hKey, ValueName, NULL, NULL, (LPBYTE)Value, &dwSize); if (rc != ERROR_SUCCESS) { TRACE("RegQueryValueEx() failed with error %lu\n", rc); goto cleanup; } /* Convert Value to a Lcid */ ValueString.Length = ValueString.MaximumLength = (USHORT)dwSize; ValueString.Buffer = Value; Status = RtlUnicodeStringToInteger(&ValueString, 16, (PULONG)&Lcid); if (!NT_SUCCESS(Status)) { TRACE("RtlUnicodeStringToInteger() failed with status 0x%08lx\n", Status); goto cleanup; } TRACE("%s language is 0x%08lx\n", UserProfile ? "User" : "System", Lcid); Status = NtSetDefaultLocale(UserProfile, Lcid); if (!NT_SUCCESS(Status)) { TRACE("NtSetDefaultLocale() failed with status 0x%08lx\n", Status); goto cleanup; } ret = TRUE; cleanup: if (hKey) RegCloseKey(hKey); if (Value) HeapFree(GetProcessHeap(), 0, Value); return ret; }
void test() { NTSTATUS tRetStatus; KdPrint(("enter teest\n")); KdPrint(("WCHAR and CHAR")); CHAR tSrc[] = "abcd"; CHAR tDes[10] = {0}; strcpy(tDes,tSrc); KdPrint(("%s\n",tDes)); WCHAR tWSrc[] = L"abcde"; WCHAR tWDes[10] = {0}; wcscpy(tWDes,tWSrc); KdPrint(("%S\n",tWDes)); KdPrint(("\n")); KdPrint(("ANSI_STRING and UNICODE_STRING\n")); ANSI_STRING tAnsiStringSrc; KdPrint(("printf ansi string(no init):%Z\n",&tAnsiStringSrc)); UNICODE_STRING tUnicodeStringSrc; KdPrint(("printf Unicode string(no init):%wZ\n",&tUnicodeStringSrc)); //RtlInitAnsiString()简单指针赋值 tUnicodeStringSrc.MaximumLength = 100; tUnicodeStringSrc.Buffer = (PWSTR)ExAllocatePool(PagedPool, tUnicodeStringSrc.MaximumLength); WCHAR tWTemp[] = L"example unicodestring"; tUnicodeStringSrc.Length = wcslen(tWTemp) * 2; //单位字节 RtlCopyMemory(tUnicodeStringSrc.Buffer, tWTemp, tUnicodeStringSrc.Length); //字节 KdPrint(("length:%d,maxlen:%d,str:%wZ\n",tUnicodeStringSrc.Length, tUnicodeStringSrc.MaximumLength, &tUnicodeStringSrc)); //RtlCopyUnicodeString()和RtlCopyMemory相似,目的缓存需要自己分配,自己清空 KdPrint(("compare string\n")); UNICODE_STRING tCompareStr; RtlInitUnicodeString(&tCompareStr,tWTemp); KdPrint(("length:%d,maxlen:%d,str:%wZ\n",tCompareStr.Length, tCompareStr.MaximumLength, &tCompareStr)); if(0 == RtlCompareUnicodeString(&tUnicodeStringSrc, &tCompareStr, FALSE)) //maxlength不同,不影响比较结果 KdPrint(("equal\n")); else KdPrint(("not equal\n")); ExFreePool(tUnicodeStringSrc.Buffer); tUnicodeStringSrc.Buffer = 0; tUnicodeStringSrc.Length = 0; tUnicodeStringSrc.MaximumLength = 0; KdPrint(("to up\n")); UNICODE_STRING tUpCaseString; tRetStatus = RtlUpcaseUnicodeString(&tUpCaseString, &tUnicodeStringSrc, TRUE); if(false == NT_SUCCESS(tRetStatus)) KdPrint(("UpcaseUnicodestring failed\n")); KdPrint(("%wZ\n",&tUpCaseString)); RtlFreeUnicodeString(&tUpCaseString); KdPrint(("oh on?\n")); UNICODE_STRING tTestUnicodeString; RtlInitUnicodeString(&tTestUnicodeString, L"aabbccdd"); KdPrint(("%wZ\n",&tTestUnicodeString)); RtlUpcaseUnicodeString(&tTestUnicodeString,&tTestUnicodeString,FALSE); KdPrint(("%wZ\n",&tTestUnicodeString)); KdPrint(("string to int\n")); UNICODE_STRING tString; RtlInitUnicodeString(&tString, L"123"); ULONG t = 0; RtlUnicodeStringToInteger(&tString, 10, &t); t = t+1; KdPrint(("convert to int:%d\n",t)); KdPrint(("level test\n")); }
NTSTATUS NTAPI ExpGetCurrentUserUILanguage(IN PWSTR MuiName, OUT LANGID* LanguageId) { UCHAR ValueBuffer[256]; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"Control Panel\\International"); UNICODE_STRING ValueName; UNICODE_STRING ValueString; ULONG ValueLength; ULONG Value; HANDLE UserKey; HANDLE KeyHandle; NTSTATUS Status; PAGED_CODE(); /* Setup the key name */ RtlInitUnicodeString(&ValueName, MuiName); /* Open the use key */ Status = RtlOpenCurrentUser(KEY_READ, &UserKey); if (!NT_SUCCESS(Status)) return Status; /* Initialize the attributes and open the key */ InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, UserKey, NULL); Status = ZwOpenKey(&KeyHandle, KEY_QUERY_VALUE,&ObjectAttributes); if (NT_SUCCESS(Status)) { /* Set buffer and query the current value */ ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation, ValueBuffer, sizeof(ValueBuffer), &ValueLength); if (NT_SUCCESS(Status)) { /* Success, is the value the right type? */ if (ValueInfo->Type == REG_SZ) { /* It is. Initialize the data and convert it */ RtlInitUnicodeString(&ValueString, (PWSTR)ValueInfo->Data); Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value); if (NT_SUCCESS(Status)) { /* Return the language */ *LanguageId = (USHORT)Value; } } else { /* Fail */ Status = STATUS_UNSUCCESSFUL; } /* Close the key */ ZwClose(KeyHandle); } } /* Close the user key and return */ ZwClose(UserKey); return Status; }
BOOLEAN RtlpGetIntegerAtom( PWSTR Name, PRTL_ATOM Atom OPTIONAL ) { NTSTATUS Status; UNICODE_STRING UnicodeString; PWSTR s; ULONG n; RTL_ATOM Temp; if (((ULONG_PTR)Name & -0x10000) == 0) { Temp = (RTL_ATOM)(USHORT)PtrToUlong(Name); if (Temp >= RTL_ATOM_MAXIMUM_INTEGER_ATOM) { return FALSE; } else { if (Temp == RTL_ATOM_INVALID_ATOM) { Temp = RTL_ATOM_MAXIMUM_INTEGER_ATOM; } if (ARGUMENT_PRESENT( Atom )) { *Atom = Temp; } return TRUE; } } else if (*Name != L'#') { return FALSE; } s = ++Name; while (*s != UNICODE_NULL) { if (*s < L'0' || *s > L'9') { return FALSE; } else { s++; } } n = 0; UnicodeString.Buffer = Name; UnicodeString.Length = (USHORT)((PCHAR)s - (PCHAR)Name); UnicodeString.MaximumLength = UnicodeString.Length; Status = RtlUnicodeStringToInteger( &UnicodeString, 10, &n ); if (NT_SUCCESS( Status )) { if (ARGUMENT_PRESENT( Atom )) { if (n == 0 || n > RTL_ATOM_MAXIMUM_INTEGER_ATOM) { *Atom = RTL_ATOM_MAXIMUM_INTEGER_ATOM; } else { *Atom = (RTL_ATOM)n; } } return TRUE; } else { return FALSE; } }
NTSTATUS NTAPI DiskSaveBusDetectInfo( IN PDRIVER_OBJECT DriverObject, IN HANDLE TargetKey, IN ULONG DiskNumber ) /*++ Routine Description: This routine will transfer the firmware/ntdetect reported information in the specified target key into the appropriate entry in the DetectInfoList. Arguments: DriverObject - the object for this driver. TargetKey - the key for the disk being saved. DiskNumber - the ordinal of the entry in the DiskPeripheral tree for this entry Return Value: status --*/ { PDISK_DETECT_INFO diskInfo; UNICODE_STRING unicodeString; PKEY_VALUE_FULL_INFORMATION keyData; ULONG length; NTSTATUS status; PAGED_CODE(); diskInfo = &(DetectInfoList[DiskNumber]); if(diskInfo->Initialized) { ASSERT(FALSE); DebugPrint((1, "DiskSaveBusDetectInfo: disk entry %#x already has a " "signature of %#08lx and mbr checksum of %#08lx\n", DiskNumber, diskInfo->Signature, diskInfo->MbrCheckSum)); return STATUS_UNSUCCESSFUL; } RtlInitUnicodeString(&unicodeString, L"Identifier"); keyData = ExAllocatePoolWithTag(PagedPool, VALUE_BUFFER_SIZE, DISK_TAG_UPDATE_GEOM); if(keyData == NULL) { DebugPrint((1, "DiskSaveBusDetectInfo: Couldn't allocate space for " "registry data\n")); return STATUS_INSUFFICIENT_RESOURCES; } // // Get disk peripheral identifier. // status = ZwQueryValueKey(TargetKey, &unicodeString, KeyValueFullInformation, keyData, VALUE_BUFFER_SIZE, &length); if(!NT_SUCCESS(status)) { DebugPrint((1, "DiskSaveBusDetectInfo: Error %#08lx getting " "Identifier\n", status)); ExFreePool(keyData); return status; } else if (keyData->DataLength < 9*sizeof(WCHAR)) { // // the data is too short to use (we subtract 9 chars in normal path) // DebugPrint((1, "DiskSaveBusDetectInfo: Saved data was invalid, " "not enough data in registry!\n")); ExFreePool(keyData); return STATUS_UNSUCCESSFUL; } else { UNICODE_STRING identifier; ULONG value; // // Complete unicode string. // identifier.Buffer = (PWSTR) ((PUCHAR)keyData + keyData->DataOffset); identifier.Length = (USHORT) keyData->DataLength; identifier.MaximumLength = (USHORT) keyData->DataLength; // // Get the first value out of the identifier - this will be the MBR // checksum. // status = RtlUnicodeStringToInteger(&identifier, 16, &value); if(!NT_SUCCESS(status)) { DebugPrint((1, "DiskSaveBusDetectInfo: Error %#08lx converting " "identifier %wZ into MBR xsum\n", status, &identifier)); ExFreePool(keyData); return status; } diskInfo->MbrCheckSum = value; // // Shift the string over to get the disk signature // identifier.Buffer += 9; identifier.Length -= 9 * sizeof(WCHAR); identifier.MaximumLength -= 9 * sizeof(WCHAR); status = RtlUnicodeStringToInteger(&identifier, 16, &value); if(!NT_SUCCESS(status)) { DebugPrint((1, "DiskSaveBusDetectInfo: Error %#08lx converting " "identifier %wZ into disk signature\n", status, &identifier)); ExFreePool(keyData); value = 0; } diskInfo->Signature = value; } // // Here is where we would save away the extended int13 data. // // // Mark this entry as initialized so we can make sure not to do it again. // diskInfo->Initialized = TRUE; return STATUS_SUCCESS; }
/// <summary> /// Get kernel build number /// </summary> /// <param name="pBuildNO">Build number.</param> /// <returns>Status code</returns> NTSTATUS BBGetBuildNO( OUT PULONG pBuildNo ) { ASSERT( pBuildNo != NULL ); if (pBuildNo == 0) return STATUS_INVALID_PARAMETER; NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING strRegKey = { 0 }; UNICODE_STRING strRegValue = { 0 }; UNICODE_STRING strVerVal = { 0 }; HANDLE hKey = NULL; OBJECT_ATTRIBUTES keyAttr = { 0 }; RtlUnicodeStringInit( &strRegKey, L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion" ); RtlUnicodeStringInit( &strRegValue, L"BuildLabEx" ); InitializeObjectAttributes( &keyAttr, &strRegKey, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL ); status = ZwOpenKey( &hKey, KEY_READ, &keyAttr ); if (NT_SUCCESS( status )) { PKEY_VALUE_FULL_INFORMATION pValueInfo = ExAllocatePoolWithTag( PagedPool, 0x1000, BB_POOL_TAG ); ULONG bytes = 0; if (pValueInfo) { status = ZwQueryValueKey( hKey, &strRegValue, KeyValueFullInformation, pValueInfo, 0x1000, &bytes ); if (NT_SUCCESS( status )) { PWCHAR pData = (PWCHAR)((PUCHAR)pValueInfo->Name + pValueInfo->NameLength); for (ULONG i = 0; i < pValueInfo->DataLength; i++) { if (pData[i] == L'.') { for (ULONG j = i + 1; j < pValueInfo->DataLength; j++) { if (pData[j] == L'.') { strVerVal.Buffer = &pData[i] + 1; strVerVal.Length = strVerVal.MaximumLength = (USHORT)((j - i) * sizeof( WCHAR )); status = RtlUnicodeStringToInteger( &strVerVal, 10, pBuildNo ); goto skip1; } } } } skip1:; } ExFreePoolWithTag( pValueInfo, BB_POOL_TAG ); } else status = STATUS_NO_MEMORY; ZwClose( hKey ); } else DPRINT( "BlackBone: %s: ZwOpenKey failed with status 0x%X\n", __FUNCTION__, status ); return status; }
BOOLEAN RosSymCreateFromFile(PVOID FileContext, PROSSYM_INFO *RosSymInfo) { IMAGE_DOS_HEADER DosHeader; IMAGE_NT_HEADERS NtHeaders; PIMAGE_SECTION_HEADER SectionHeaders; unsigned SectionIndex; unsigned SymbolTable, NumSymbols; /* Load DOS header */ if (! RosSymSeekFile(FileContext, 0)) { werrstr("Could not rewind file\n"); return FALSE; } if (! RosSymReadFile(FileContext, &DosHeader, sizeof(IMAGE_DOS_HEADER))) { werrstr("Failed to read DOS header %x\n", RosSymStatus); return FALSE; } if (! ROSSYM_IS_VALID_DOS_HEADER(&DosHeader)) { werrstr("Image doesn't have a valid DOS header\n"); return FALSE; } /* Load NT headers */ if (! RosSymSeekFile(FileContext, DosHeader.e_lfanew)) { werrstr("Failed seeking to NT headers\n"); return FALSE; } if (! RosSymReadFile(FileContext, &NtHeaders, sizeof(IMAGE_NT_HEADERS))) { werrstr("Failed to read NT headers\n"); return FALSE; } if (! ROSSYM_IS_VALID_NT_HEADERS(&NtHeaders)) { werrstr("Image doesn't have a valid PE header\n"); return FALSE; } SymbolTable = NtHeaders.FileHeader.PointerToSymbolTable; NumSymbols = NtHeaders.FileHeader.NumberOfSymbols; if (!NumSymbols) { werrstr("Image doesn't have debug symbols\n"); return FALSE; } DPRINT("SymbolTable %x NumSymbols %x\n", SymbolTable, NumSymbols); /* Load section headers */ if (! RosSymSeekFile(FileContext, (char *) IMAGE_FIRST_SECTION(&NtHeaders) - (char *) &NtHeaders + DosHeader.e_lfanew)) { werrstr("Failed seeking to section headers\n"); return FALSE; } DPRINT("Alloc section headers\n"); SectionHeaders = RosSymAllocMem(NtHeaders.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER)); if (NULL == SectionHeaders) { werrstr("Failed to allocate memory for %u section headers\n", NtHeaders.FileHeader.NumberOfSections); return FALSE; } if (! RosSymReadFile(FileContext, SectionHeaders, NtHeaders.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))) { RosSymFreeMem(SectionHeaders); werrstr("Failed to read section headers\n"); return FALSE; } // Convert names to ANSI_STRINGs for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; SectionIndex++) { ANSI_STRING astr; if (SectionHeaders[SectionIndex].Name[0] != '/') { DPRINT("Short name string %d, %s\n", SectionIndex, SectionHeaders[SectionIndex].Name); astr.Buffer = RosSymAllocMem(IMAGE_SIZEOF_SHORT_NAME); memcpy(astr.Buffer, SectionHeaders[SectionIndex].Name, IMAGE_SIZEOF_SHORT_NAME); astr.MaximumLength = IMAGE_SIZEOF_SHORT_NAME; astr.Length = GetStrnlen(astr.Buffer, IMAGE_SIZEOF_SHORT_NAME); } else { UNICODE_STRING intConv; NTSTATUS Status; ULONG StringOffset; Status = RtlCreateUnicodeStringFromAsciiz(&intConv, (PCSZ)SectionHeaders[SectionIndex].Name + 1); if (!NT_SUCCESS(Status)) goto freeall; Status = RtlUnicodeStringToInteger(&intConv, 10, &StringOffset); RtlFreeUnicodeString(&intConv); if (!NT_SUCCESS(Status)) goto freeall; if (!RosSymSeekFile(FileContext, SymbolTable + NumSymbols * SYMBOL_SIZE + StringOffset)) goto freeall; astr.Buffer = RosSymAllocMem(MAXIMUM_DWARF_NAME_SIZE); if (!RosSymReadFile(FileContext, astr.Buffer, MAXIMUM_DWARF_NAME_SIZE)) goto freeall; astr.Length = GetStrnlen(astr.Buffer, MAXIMUM_DWARF_NAME_SIZE); astr.MaximumLength = MAXIMUM_DWARF_NAME_SIZE; DPRINT("Long name %d, %s\n", SectionIndex, astr.Buffer); } *ANSI_NAME_STRING(&SectionHeaders[SectionIndex]) = astr; } DPRINT("Done with sections\n"); Pe *pe = RosSymAllocMem(sizeof(*pe)); pe->fd = FileContext; pe->e2 = peget2; pe->e4 = peget4; pe->e8 = peget8; pe->nsections = NtHeaders.FileHeader.NumberOfSections; pe->sect = SectionHeaders; pe->imagebase = pe->loadbase = NtHeaders.OptionalHeader.ImageBase; pe->imagesize = NtHeaders.OptionalHeader.SizeOfImage; pe->codestart = NtHeaders.OptionalHeader.BaseOfCode; pe->datastart = NtHeaders.OptionalHeader.BaseOfData; pe->loadsection = loaddisksection; *RosSymInfo = dwarfopen(pe); return TRUE; freeall: for (SectionIndex = 0; SectionIndex < NtHeaders.FileHeader.NumberOfSections; SectionIndex++) RtlFreeAnsiString(ANSI_NAME_STRING(&SectionHeaders[SectionIndex])); RosSymFreeMem(SectionHeaders); return FALSE; }