BOOL DBI1::fSave() { // output the any deferred udt defns from foreign type servers int doCount = 0; do { fUDTOutsideRef = FALSE; for (OTM *potm = potmTSHead ; potm; potm = potm->pNext) { if (potm->ptm) if (!potm->ptm->fPackDeferredUDTDefns()) return FALSE; } expect(doCount < 2); doCount++; } while (fUDTOutsideRef); if ( !pgsiGS->fSave(&(dbihdr.snGSSyms)) || !pgsiPS->fSave(&(dbihdr.snPSSyms)) || !writeSymRecs()) return FALSE; if (pscEnd) { // sort entries in the SC qsort(bufSC.Start(), pscEnd - (SC*)bufSC.Start(), sizeof(SC), SCCmp); } // record lengths of the gpmodi and sc substreams in the header and then // emit the dbi stream dbihdr.cbGpModi = bufGpmodi.Size(); dbihdr.cbSC = (PB)pscEnd - bufSC.Start(); dbihdr.cbSecMap = bufSecMap.Size(); expect(fAlign(dbihdr.cbGpModi)); expect(fAlign(dbihdr.cbSC)); expect(fAlign(dbihdr.cbSecMap)); // Convert the file info in the gpmodi into sstFileIndex format // and save that! Buffer bufFileInfo; if (!QueryFileInfo(0, &dbihdr.cbFileInfo) || !bufFileInfo.Reserve(dbihdr.cbFileInfo) || !QueryFileInfo(bufFileInfo.Start(), &dbihdr.cbFileInfo)) return FALSE; expect(fAlign(sizeof(dbihdr))); expect(fAlign(dbihdr.cbFileInfo)); if (!MSFReplaceStream(ppdb1->pmsf, snDbi, &dbihdr, sizeof (dbihdr)) || !MSFAppendStream(ppdb1->pmsf, snDbi, bufGpmodi.Start(), dbihdr.cbGpModi) || !MSFAppendStream(ppdb1->pmsf, snDbi, bufSC.Start(), dbihdr.cbSC) || !MSFAppendStream(ppdb1->pmsf, snDbi, bufSecMap.Start(), dbihdr.cbSecMap) || !MSFAppendStream(ppdb1->pmsf, snDbi, bufFileInfo.Start(), dbihdr.cbFileInfo)){ ppdb1->setWriteError(); return FALSE; } return TRUE; }
static VOID TestAllInformation(VOID) { NTSTATUS Status; UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntoskrnl.exe"); UNICODE_STRING Ntoskrnl = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandle; IO_STATUS_BLOCK IoStatus; PFILE_ALL_INFORMATION FileAllInfo; SIZE_T Length; ULONG NameLength; PWCHAR Name = NULL; UNICODE_STRING NamePart; InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&FileHandle, SYNCHRONIZE | FILE_READ_ATTRIBUTES, &ObjectAttributes, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE); if (Status == STATUS_PENDING) { Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL); ok_eq_hex(Status, STATUS_SUCCESS); Status = IoStatus.Status; } ok_eq_hex(Status, STATUS_SUCCESS); if (skip(NT_SUCCESS(Status), "No file handle, %lx\n", Status)) return; /* NtQueryInformationFile doesn't do length checks for kernel callers in a free build */ if (KmtIsCheckedBuild) { /* Zero length */ Length = 0; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH); ok_eq_size(Length, (ULONG_PTR)0x5555555555555555); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One less than the minimum */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) - 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_INFO_LENGTH_MISMATCH); ok_eq_size(Length, (ULONG_PTR)0x5555555555555555); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); } /* The minimum allowed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName)); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* Plenty of space -- determine NameLength and copy the name */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + MAX_PATH * sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); if (!skip(NT_SUCCESS(Status) && FileAllInfo != NULL, "No info\n")) { NameLength = FileAllInfo->NameInformation.FileNameLength; ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); Name = ExAllocatePoolWithTag(PagedPool, NameLength + sizeof(UNICODE_NULL), 'sFmK'); if (!skip(Name != NULL, "Could not allocate %lu bytes\n", NameLength + (ULONG)sizeof(UNICODE_NULL))) { RtlCopyMemory(Name, FileAllInfo->NameInformation.FileName, NameLength); Name[NameLength / sizeof(WCHAR)] = UNICODE_NULL; ok(Name[0] == L'\\', "Name is %ls, expected first char to be \\\n", Name); ok(NameLength >= Ntoskrnl.Length + sizeof(WCHAR), "NameLength %lu too short\n", NameLength); if (NameLength >= Ntoskrnl.Length) { NamePart.Buffer = Name + (NameLength - Ntoskrnl.Length) / sizeof(WCHAR); NamePart.Length = Ntoskrnl.Length; NamePart.MaximumLength = NamePart.Length; ok(RtlEqualUnicodeString(&NamePart, &Ntoskrnl, TRUE), "Name ends in '%wZ', expected %wZ\n", &NamePart, &Ntoskrnl); } } ok(FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)] == 0xdddd, "Char past FileName is %x\n", FileAllInfo->NameInformation.FileName[NameLength / sizeof(WCHAR)]); } if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One char less than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - sizeof(WCHAR)); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One byte less than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_BUFFER_OVERFLOW); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength - 1); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* Exactly the required size */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One byte more than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + 1; Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); /* One char more than needed */ Length = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength + sizeof(WCHAR); Status = QueryFileInfo(FileHandle, (PVOID*)&FileAllInfo, &Length, FileAllInformation); ok_eq_hex(Status, STATUS_SUCCESS); ok_eq_size(Length, FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + NameLength); if (FileAllInfo) KmtFreeGuarded(FileAllInfo); ExFreePoolWithTag(Name, 'sFmK'); Status = ObCloseHandle(FileHandle, KernelMode); ok_eq_hex(Status, STATUS_SUCCESS); }