NTSTATUS __fastcall NtGetFileId(POBJECT_ATTRIBUTES ObjectAttributes, FILE_STANDARD_INFORMATION* pFileStandardInfo, FILE_INTERNAL_INFORMATION* pFileInternalInfo) { HANDLE hFile; //OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(OBJECT_ATTRIBUTES), hRootDir, (UNICODE_STRING*)&FileName, OBJ_CASE_INSENSITIVE }; IO_STATUS_BLOCK IoStatusBlock; auto Status = NtOpenFile(&hFile, SYNCHRONIZE, ObjectAttributes, &IoStatusBlock, FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); if (Status) return Status; if (pFileStandardInfo) { if (Status = NtQueryInformationFile(hFile, &IoStatusBlock, pFileStandardInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation)) { goto End; } } if (pFileInternalInfo) { if (Status = NtQueryInformationFile(hFile, &IoStatusBlock, pFileInternalInfo, sizeof(FILE_INTERNAL_INFORMATION), FileInternalInformation)) { goto End; } } End: NtClose(hFile); return Status; }
DWORD GetFileAttributes2(POBJECT_ATTRIBUTES ObjectAttributes) { HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; auto Status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES | SYNCHRONIZE, ObjectAttributes, &IoStatusBlock, FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); if (Status) { goto Error; } FILE_BASIC_INFORMATION Info; Status = NtQueryInformationFile(hFile, &IoStatusBlock, &Info, sizeof(Info), FileBasicInformation); NtClose(hFile); if (Status) { Error: SetLastError(RtlNtStatusToDosError(Status)); return -1; } else { return Info.FileAttributes; } }
static NTSTATUS SetLastWriteTime( HANDLE FileHandle, LARGE_INTEGER LastWriteTime ) { NTSTATUS errCode = STATUS_SUCCESS; IO_STATUS_BLOCK IoStatusBlock; FILE_BASIC_INFORMATION FileBasic; errCode = NtQueryInformationFile (FileHandle, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(errCode)) { WARN("Error 0x%08x obtaining FileBasicInformation\n", errCode); } else { FileBasic.LastWriteTime.QuadPart = LastWriteTime.QuadPart; errCode = NtSetInformationFile (FileHandle, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(errCode)) { WARN("Error 0x%0x setting LastWriteTime\n", errCode); } } return errCode; }
int XGetFileSize(int handle, unsigned int *filesize) { NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock; FILE_NETWORK_OPEN_INFORMATION openInfo; #ifdef DEBUG debugPrint("XGetFileSize handle=%08x\n", handle); #endif // We use FileNetworkOpenInformation from NtQueryInformationFile to get // the file size. This trick I got from Windows XP's implementation, // which seems to work on XBOX. status = NtQueryInformationFile( (void*)handle, &ioStatusBlock, &openInfo, sizeof(openInfo), FileNetworkOpenInformation); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); else { if (filesize) *filesize = (unsigned int)openInfo.EndOfFile.u.LowPart; return STATUS_SUCCESS; } }
/* retrieve the DeviceIoControl function for a Vxd given a file handle */ static DeviceIoProc get_vxd_proc( HANDLE handle ) { DeviceIoProc ret = NULL; int status, i; IO_STATUS_BLOCK io; FILE_INTERNAL_INFORMATION info; status = NtQueryInformationFile( handle, &io, &info, sizeof(info), FileInternalInformation ); if (status) { SetLastError( RtlNtStatusToDosError(status) ); return NULL; } RtlEnterCriticalSection( &vxd_section ); for (i = 0; i < MAX_VXD_MODULES; i++) { if (!vxd_modules[i].module) break; if (vxd_modules[i].index.QuadPart == info.IndexNumber.QuadPart) { if (!(ret = vxd_modules[i].proc)) SetLastError( ERROR_INVALID_FUNCTION ); goto done; } } /* FIXME: Here we could go through the directory to find the VxD name and load it. */ /* Let's wait to find out if there are actually apps out there that try to share */ /* VxD handles between processes, before we go to the trouble of implementing it. */ ERR( "handle %p not found in module list, inherited from another process?\n", handle ); done: RtlLeaveCriticalSection( &vxd_section ); return ret; }
int XSetFilePointer( int handle, int distanceToMove, int *newFilePointer, int moveMethod) { FILE_POSITION_INFORMATION positionInfo; LARGE_INTEGER targetPointer; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; int filesize; #ifdef DEBUG debugPrint("XSetFilePointer handle=%08x distance=%08x method=%02x\n", handle, distanceToMove, moveMethod); #endif // Calculate the target pointer switch (moveMethod) { case FILE_BEGIN: // From the beginning of the file targetPointer.u.HighPart = 0; targetPointer.u.LowPart = distanceToMove; break; case FILE_CURRENT: // From the current position status = NtQueryInformationFile((void*)handle, &ioStatusBlock, &positionInfo, sizeof(positionInfo), FilePositionInformation); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); targetPointer.u.HighPart = 0; targetPointer.u.LowPart = positionInfo.CurrentByteOffset.u.LowPart + distanceToMove; break; case FILE_END: // From the end of the file status = XGetFileSize(handle, &filesize); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); targetPointer.u.HighPart = 0; targetPointer.u.LowPart -= distanceToMove; break; default: return ERROR_INVALID_PARAMETER; } // Don't allow a negative seek if ((targetPointer.u.LowPart & 0x80000000) != 0) return ERROR_NEGATIVE_SEEK; // Fill in the new position information positionInfo.CurrentByteOffset.u.HighPart = targetPointer.u.HighPart; positionInfo.CurrentByteOffset.u.LowPart= targetPointer.u.LowPart; // Set the new position status = NtSetInformationFile((void*)handle, &ioStatusBlock, &positionInfo, sizeof(positionInfo), FilePositionInformation); if (!NT_SUCCESS(status)) return RtlNtStatusToDosError(status); else { if (newFilePointer) *newFilePointer = targetPointer.u.LowPart; return STATUS_SUCCESS; } }
/** * Wrapper for getting FILE_PIPE_LOCAL_INFORMATION via the NT API. * * @returns Success indicator (true/false). * @param pThis The pipe. * @param pInfo The info structure. */ static bool rtPipeQueryInfo(RTPIPEINTERNAL *pThis, FILE_PIPE_LOCAL_INFORMATION *pInfo) { IO_STATUS_BLOCK Ios; RT_ZERO(Ios); RT_ZERO(*pInfo); NTSTATUS rcNt = NtQueryInformationFile(pThis->hPipe, &Ios, pInfo, sizeof(*pInfo), FilePipeLocalInformation); return rcNt >= 0; }
BOOL CFileControlTool::GetFileName( HANDLE h, LPTSTR str, DWORD processId ) { BOOL ret= FALSE; HANDLE hThread = NULL; GetFileNameThreadParam tp; HANDLE handle; HANDLE hRemoteProcess = NULL; BOOL remote = processId != GetCurrentProcessId(); if ( remote ) { // Open process hRemoteProcess = OpenProcess(PROCESS_DUP_HANDLE,TRUE,processId); if ( hRemoteProcess == NULL ) return FALSE; // Duplicate handle DuplicateHandle(hRemoteProcess,h,GetCurrentProcess(),&handle,0,FALSE,DUPLICATE_SAME_ACCESS); } else handle = h; tp.hFile = handle; tp.pName = str; tp.rc = 0; // Let's start the thread to get the file name DWORD dwThreadId = 0; FILE_NAME_INFORMATION lpFileNameInfo; DWORD iob[2]; tp.rc = NtQueryInformationFile(handle, iob, &lpFileNameInfo, sizeof(FILE_NAME_INFORMATION),FileNameInformation); if ( tp.rc == 0 ) MbsToWcs((LPCSTR)lpFileNameInfo.FileName,tp.pName); //_tcsncpy(tp.pName,lpFileNameInfo.FileName,lpFileNameInfo.FileNameLength); ret = ( tp.rc == 0 ); cleanup: if ( remote ) { if ( hRemoteProcess != NULL ) CloseHandle( hRemoteProcess ); if ( handle != NULL ) CloseHandle( handle ); } return ret; }
/* * @implemented */ BOOL WINAPI GetMailslotInfo(IN HANDLE hMailslot, IN LPDWORD lpMaxMessageSize, IN LPDWORD lpNextSize, IN LPDWORD lpMessageCount, IN LPDWORD lpReadTimeout) { FILE_MAILSLOT_QUERY_INFORMATION Buffer; IO_STATUS_BLOCK Iosb; NTSTATUS Status; LARGE_INTEGER Timeout; Status = NtQueryInformationFile(hMailslot, &Iosb, &Buffer, sizeof(FILE_MAILSLOT_QUERY_INFORMATION), FileMailslotQueryInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtQueryInformationFile failed (Status %x)!\n", Status); BaseSetLastNTError(Status); return FALSE; } if (lpMaxMessageSize) *lpMaxMessageSize = Buffer.MaximumMessageSize; if (lpNextSize) *lpNextSize = Buffer.NextMessageSize; if (lpMessageCount) *lpMessageCount = Buffer.MessagesAvailable; if (lpReadTimeout) { if (Buffer.ReadTimeout.QuadPart == 0xFFFFFFFFFFFFFFFFLL) { *lpReadTimeout = MAILSLOT_WAIT_FOREVER; } else { Timeout.QuadPart = -Buffer.ReadTimeout.QuadPart; Timeout = RtlExtendedLargeIntegerDivide(Timeout, 10000, NULL); if (Timeout.HighPart == 0) { *lpReadTimeout = Timeout.LowPart; } else { *lpReadTimeout = 0xFFFFFFFE; } } } return TRUE; }
BOOL BackupReadData(HANDLE hFile, BACKUPCONTEXT *pbuc, BACKUPIOFRAME *pbif) { NTSTATUS Status; IO_STATUS_BLOCK iosb; if (pbuc->fStreamStart) { LARGE_INTEGER licbFile; FILE_STANDARD_INFORMATION fsi; RtlZeroMemory(&fsi, sizeof(fsi)); Status = NtQueryInformationFile( hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation); if (!NT_SUCCESS(Status) || fsi.Directory) { return(TRUE); } licbFile.LowPart = GetFileSize(hFile, &licbFile.HighPart); if (licbFile.LowPart == 0 && licbFile.HighPart == 0) { return(TRUE); } if (licbFile.LowPart == 0xffffffff && GetLastError() != NO_ERROR) { return(FALSE); } pbuc->head.Size = licbFile; pbuc->head.dwStreamId = mwStreamList[pbuc->StreamIndex]; pbuc->head.dwStreamAttributes = STREAM_NORMAL_ATTRIBUTE; pbuc->head.dwStreamNameSize = 0; pbuc->cbHeader = CB_NAMELESSHEADER; pbuc->fStreamStart = FALSE; licbFile.HighPart = 0; SetFilePointer(hFile, 0, &licbFile.HighPart, FILE_BEGIN); return(TRUE); } if (pbuc->liStreamOffset.HighPart != 0 || pbuc->liStreamOffset.LowPart >= pbuc->cbHeader) { return(BackupReadStream(hFile, pbuc, pbif)); } return(TRUE); }
/* * FUNCTION: Sets attributes on a file * ARGUMENTS: * File = Pointer to CFFILE node for file * RETURNS: * Status of operation */ static BOOL SetAttributesOnFile(PCFFILE File, HANDLE hFile) { FILE_BASIC_INFORMATION FileBasic; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS NtStatus; ULONG Attributes = 0; if (File->Attributes & CAB_ATTRIB_READONLY) Attributes |= FILE_ATTRIBUTE_READONLY; if (File->Attributes & CAB_ATTRIB_HIDDEN) Attributes |= FILE_ATTRIBUTE_HIDDEN; if (File->Attributes & CAB_ATTRIB_SYSTEM) Attributes |= FILE_ATTRIBUTE_SYSTEM; if (File->Attributes & CAB_ATTRIB_DIRECTORY) Attributes |= FILE_ATTRIBUTE_DIRECTORY; if (File->Attributes & CAB_ATTRIB_ARCHIVE) Attributes |= FILE_ATTRIBUTE_ARCHIVE; NtStatus = NtQueryInformationFile(hFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); } else { FileBasic.FileAttributes = Attributes; NtStatus = NtSetInformationFile(hFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); } } return NT_SUCCESS(NtStatus); }
/* Return value: * < 0: errno * = 0: Not a special file of the specified header * > 0: Bytes read */ int winfs_read_special_file(struct file *f, const char *header, int headerlen, char *buf, int buflen) { if (!winfs_is_winfile(f)) { log_warning("Not a winfile."); return 0; } struct winfs_file *winfile = (struct winfs_file *)f; /* Test if the system attribute is set */ FILE_ATTRIBUTE_TAG_INFORMATION info; IO_STATUS_BLOCK status_block; NTSTATUS status; status = NtQueryInformationFile(winfile->handle, &status_block, &info, sizeof(info), FileAttributeTagInformation); if (!NT_SUCCESS(status)) { log_warning("NtQueryInformationFile() failed, status: %x", status); return 0; } if (!(info.FileAttributes & FILE_ATTRIBUTE_SYSTEM)) { log_warning("System attribute is not set."); return 0; } /* The if the header matches */ char *file_header = (char *)alloca(headerlen); DWORD num_read; OVERLAPPED overlapped; overlapped.Internal = 0; overlapped.InternalHigh = 0; overlapped.Offset = 0; overlapped.OffsetHigh = 0; overlapped.hEvent = 0; if (!ReadFile(winfile->handle, file_header, headerlen, &num_read, &overlapped) || num_read < headerlen) { log_warning("ReadFile() failed, error code: %d", GetLastError()); return 0; } if (memcmp(file_header, header, headerlen)) { log_warning("File header mismatch."); return 0; } /* Read special content */ overlapped.Offset = headerlen; if (!ReadFile(winfile->handle, buf, buflen, &num_read, &overlapped)) return 0; return num_read; }
int NumberOfLinks(char *FileName) { FILE_STANDARD_INFORMATION FileInfo; WCHAR FileNameBuf[MAX_PATH + 50]; HANDLE FileHandle; NTSTATUS Status; IO_STATUS_BLOCK Iosb; OBJECT_ATTRIBUTES Obj; UNICODE_STRING uPrelimFileName, uFileName; RtlCreateUnicodeStringFromAsciiz(&uPrelimFileName, FileName); lstrcpy(FileNameBuf, L"\\DosDevices\\"); lstrcat(FileNameBuf, uPrelimFileName.Buffer); RtlInitUnicodeString(&uFileName, FileNameBuf); InitializeObjectAttributes(&Obj, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&FileHandle, SYNCHRONIZE, &Obj, &Iosb, SHARE_ALL, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return 0; } Status = NtQueryInformationFile(FileHandle, &Iosb, &FileInfo, sizeof(FileInfo), FileStandardInformation); NtClose(FileHandle); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return 0; } return FileInfo.NumberOfLinks; }
/** * Queries information from a file or directory handle. * * This is shared between the RTPathQueryInfo, RTFileQueryInfo and * RTDirQueryInfo code. * * @returns IPRT status code. * @param hFile The handle to query information from. Must have * the necessary privileges. * @param pvBuf Pointer to a scratch buffer. * @param cbBuf The size of the buffer. This must be large * enough to hold a FILE_ALL_INFORMATION struct. * @param pObjInfo Where to return information about the handle. * @param enmAddAttr What extra info to return. * @param pszPath The path if this is a file (for exe detect). * @param uReparseTag The reparse tag number (0 if not applicable) for * symlink detection/whatnot. */ DECLHIDDEN(int) rtPathNtQueryInfoFromHandle(HANDLE hFile, void *pvBuf, size_t cbBuf, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr, const char *pszPath, ULONG uReparseTag) { Assert(cbBuf >= sizeof(FILE_ALL_INFORMATION)); /** @todo Try optimize this for when RTFSOBJATTRADD_UNIX isn't set? */ IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER; NTSTATUS rcNt = NtQueryInformationFile(hFile, &Ios, pvBuf, sizeof(FILE_ALL_INFORMATION), FileAllInformation); if ( NT_SUCCESS(rcNt) || rcNt == STATUS_BUFFER_OVERFLOW) { FILE_ALL_INFORMATION *pAllInfo = (FILE_ALL_INFORMATION *)pvBuf; pObjInfo->cbObject = pAllInfo->StandardInformation.EndOfFile.QuadPart; pObjInfo->cbAllocated = pAllInfo->StandardInformation.AllocationSize.QuadPart; RTTimeSpecSetNtTime(&pObjInfo->BirthTime, pAllInfo->BasicInformation.CreationTime.QuadPart); RTTimeSpecSetNtTime(&pObjInfo->AccessTime, pAllInfo->BasicInformation.LastAccessTime.QuadPart); RTTimeSpecSetNtTime(&pObjInfo->ModificationTime, pAllInfo->BasicInformation.LastWriteTime.QuadPart); RTTimeSpecSetNtTime(&pObjInfo->ChangeTime, pAllInfo->BasicInformation.ChangeTime.QuadPart); pObjInfo->Attr.fMode = rtFsModeFromDos( (pAllInfo->BasicInformation.FileAttributes << RTFS_DOS_SHIFT) & RTFS_DOS_MASK_NT, pszPath, pszPath ? strlen(pszPath) : 0, uReparseTag); pObjInfo->Attr.enmAdditional = enmAddAttr; if (enmAddAttr == RTFSOBJATTRADD_UNIX) { pObjInfo->Attr.u.Unix.uid = ~0U; pObjInfo->Attr.u.Unix.gid = ~0U; pObjInfo->Attr.u.Unix.cHardlinks = RT_MAX(1, pAllInfo->StandardInformation.NumberOfLinks); pObjInfo->Attr.u.Unix.INodeIdDevice = 0; /* below */ pObjInfo->Attr.u.Unix.INodeId = pAllInfo->InternalInformation.IndexNumber.QuadPart; pObjInfo->Attr.u.Unix.fFlags = 0; pObjInfo->Attr.u.Unix.GenerationId = 0; pObjInfo->Attr.u.Unix.Device = 0; /* Get the serial number. */ rcNt = NtQueryVolumeInformationFile(hFile, &Ios, pvBuf, (ULONG)RT_MIN(cbBuf, _2K), FileFsVolumeInformation); if (NT_SUCCESS(rcNt) || rcNt == STATUS_BUFFER_OVERFLOW) { FILE_FS_VOLUME_INFORMATION *pVolInfo = (FILE_FS_VOLUME_INFORMATION *)pvBuf; pObjInfo->Attr.u.Unix.INodeIdDevice = pVolInfo->VolumeSerialNumber; } } return rtPathNtQueryInfoFillInDummyData(VINF_SUCCESS, pObjInfo, enmAddAttr); } return RTErrConvertFromNtStatus(rcNt); }
/* * @implemented */ BOOL WINAPI GetNamedPipeInfo(HANDLE hNamedPipe, LPDWORD lpFlags, LPDWORD lpOutBufferSize, LPDWORD lpInBufferSize, LPDWORD lpMaxInstances) { FILE_PIPE_LOCAL_INFORMATION PipeLocalInformation; IO_STATUS_BLOCK StatusBlock; NTSTATUS Status; Status = NtQueryInformationFile(hNamedPipe, &StatusBlock, &PipeLocalInformation, sizeof(FILE_PIPE_LOCAL_INFORMATION), FilePipeLocalInformation); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); return FALSE; } if (lpFlags != NULL) { *lpFlags = (PipeLocalInformation.NamedPipeEnd == FILE_PIPE_SERVER_END) ? PIPE_SERVER_END : PIPE_CLIENT_END; *lpFlags |= (PipeLocalInformation.NamedPipeType == 1) ? PIPE_TYPE_MESSAGE : PIPE_TYPE_BYTE; } if (lpOutBufferSize != NULL) *lpOutBufferSize = PipeLocalInformation.OutboundQuota; if (lpInBufferSize != NULL) *lpInBufferSize = PipeLocalInformation.InboundQuota; if (lpMaxInstances != NULL) { if (PipeLocalInformation.MaximumInstances >= 255) *lpMaxInstances = PIPE_UNLIMITED_INSTANCES; else *lpMaxInstances = PipeLocalInformation.MaximumInstances; } return TRUE; }
BOOLEAN QueryVolumeInformation( HANDLE Handle, PULONG AlignmentMask, PULONG SectorSize ) { FILE_ALIGNMENT_INFORMATION AlignmentInfo; DISK_GEOMETRY DiskGeometry; IO_STATUS_BLOCK status_block; NTSTATUS status; status = NtQueryInformationFile( Handle, &status_block, &AlignmentInfo, sizeof( AlignmentInfo ), FileAlignmentInformation ); if( !NT_SUCCESS(status) ) { return FALSE; } *AlignmentMask = AlignmentInfo.AlignmentRequirement; status = NtDeviceIoControlFile( Handle, 0, NULL, NULL, &status_block, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &DiskGeometry, sizeof( DiskGeometry ) ); if( !NT_SUCCESS(status) ) { return FALSE; } *SectorSize = DiskGeometry.BytesPerSector; return TRUE; }
//获取文件物理大小 UINT64 GetFileAllocationSize(LPCWSTR FilePath) { HANDLE hFile = CreateFile(FilePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); FILE_STANDARD_INFORMATION info = { 0 }; if (hFile != INVALID_HANDLE_VALUE) { IO_STATUS_BLOCK IoStatusBlock; NtQueryInformationFile(hFile, &IoStatusBlock, &info, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); //GetFileInformationByHandleEx(hFile, FileStandardInfo, &info, sizeof(info)); CloseHandle(hFile); } return info.AllocationSize.QuadPart; }
NTSTATUS NTAPI SmpGetPagingFileSize(IN PUNICODE_STRING FileName, OUT PLARGE_INTEGER Size) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; FILE_STANDARD_INFORMATION StandardInfo; DPRINT("SMSS:PFILE: Trying to get size for `%wZ'\n", FileName); Size->QuadPart = 0; InitializeObjectAttributes(&ObjectAttributes, FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) return Status; Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &StandardInfo, sizeof(StandardInfo), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT1("SMSS:PFILE: Failed query for size potential pagefile `%wZ' with status %X \n", FileName, Status); NtClose(FileHandle); return Status; } NtClose(FileHandle); Size->QuadPart = StandardInfo.AllocationSize.QuadPart; return STATUS_SUCCESS; }
BOOL BackupReadOleData(HANDLE hFile, BACKUPCONTEXT *pbuc, BACKUPIOFRAME *pbif) { if (pbuc->fStreamStart) { IO_STATUS_BLOCK iosb; NTSTATUS Status; FILE_OLE_INFORMATION *pfoi = (FILE_OLE_INFORMATION *) pbuc->pBuffer; Status = NtQueryInformationFile( hFile, &iosb, pfoi, sizeof(*pfoi), FileOleInformation); if (!NT_SUCCESS(Status)) { if (Status == STATUS_INVALID_PARAMETER) { return(TRUE); // Downlevel filesystem - unsupported infolevel } BaseSetLastNTError(Status); return(FALSE); } pbuc->fBufferReady = TRUE; pbuc->head.dwStreamId = mwStreamList[pbuc->StreamIndex]; pbuc->head.dwStreamAttributes = STREAM_NORMAL_ATTRIBUTE; pbuc->head.dwStreamNameSize = 0; pbuc->cbHeader = CB_NAMELESSHEADER; pbuc->head.Size.HighPart = 0; pbuc->head.Size.LowPart = sizeof(*pfoi); pbuc->fStreamStart = FALSE; } else if (pbuc->liStreamOffset.HighPart != 0 || pbuc->liStreamOffset.LowPart >= pbuc->cbHeader) { BackupReadBuffer(pbuc, pbif); } return(TRUE); }
/* * @implemented */ VOID WINAPI BaseMarkFileForDelete(IN HANDLE FileHandle, IN ULONG FileAttributes) { IO_STATUS_BLOCK IoStatusBlock; FILE_BASIC_INFORMATION FileBasicInfo; FILE_DISPOSITION_INFORMATION FileDispositionInfo; /* If no attributes were given, get them */ if (!FileAttributes) { FileBasicInfo.FileAttributes = 0; NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FileBasicInfo), FileBasicInformation); FileAttributes = FileBasicInfo.FileAttributes; } /* If file is marked as RO, reset its attributes */ if (FileAttributes & FILE_ATTRIBUTE_READONLY) { RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo)); FileBasicInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL; NtSetInformationFile(FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FileBasicInfo), FileBasicInformation); } /* Finally, mark the file for deletion */ FileDispositionInfo.DeleteFile = TRUE; NtSetInformationFile(FileHandle, &IoStatusBlock, &FileDispositionInfo, sizeof(FileDispositionInfo), FileDispositionInformation); }
int main() { wcscpy(path+4,GetModulePath()); LPWSTR p=path; while (*p) p++; while (*p!=L'\\') p--; p--; while (*p!=L'\\') p--; p++; wcscpy(p,L"version.h"); UNICODE_STRING us; RtlInitUnicodeString(&us,path); OBJECT_ATTRIBUTES oa={sizeof(oa),0,&us,OBJ_CASE_INSENSITIVE,0,0}; HANDLE hFile; IO_STATUS_BLOCK isb; if (!NT_SUCCESS(NtCreateFile(&hFile, FILE_SHARE_READ|FILE_WRITE_DATA|FILE_READ_ATTRIBUTES|SYNCHRONIZE ,&oa,&isb,0,0,FILE_SHARE_READ,FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,0,0))) return 1; FILE_BASIC_INFORMATION basic; NtQueryInformationFile(hFile,&isb,&basic,sizeof(basic),FileBasicInformation); int l=strlen(buffer); char* ptr; ptr=buffer+l; LARGE_INTEGER current_time; TIME_FIELDS tf,ctf; NtQuerySystemTime(¤t_time); current_time.QuadPart-=GetTimeBias()->QuadPart; RtlTimeToTimeFields(¤t_time,&tf); RtlTimeToTimeFields(&basic.LastWriteTime,&ctf); if (ctf.wDay!=tf.wDay||ctf.wMonth!=tf.wMonth||ctf.wYear!=tf.wYear){ l+=sprintf(ptr,"%.4d.%.2d.%.2d)\\r\\n\";",tf.wYear,tf.wMonth,tf.wDay); NtWriteFile(hFile,0,0,0,&isb,buffer,l,0,0); } NtClose(hFile); return 0; //IthCloseSystemService(); }
DWORD WINAPI GetCompressedFileSizeW( LPCWSTR lpFileName, LPDWORD lpFileSizeHigh ) { NTSTATUS Status; OBJECT_ATTRIBUTES Obja; HANDLE Handle; UNICODE_STRING FileName; IO_STATUS_BLOCK IoStatusBlock; FILE_COMPRESSION_INFORMATION CompressionInfo; BOOLEAN TranslationStatus; RTL_RELATIVE_NAME RelativeName; PVOID FreeBuffer; DWORD FileSizeLow; TranslationStatus = RtlDosPathNameToNtPathName_U( lpFileName, &FileName, NULL, &RelativeName ); if ( !TranslationStatus ) { SetLastError(ERROR_PATH_NOT_FOUND); return (DWORD)-1; } FreeBuffer = FileName.Buffer; if ( RelativeName.RelativeName.Length ) { FileName = *(PUNICODE_STRING)&RelativeName.RelativeName; } else { RelativeName.ContainingDirectory = NULL; } InitializeObjectAttributes( &Obja, &FileName, OBJ_CASE_INSENSITIVE, RelativeName.ContainingDirectory, NULL ); // // Open the file // Status = NtOpenFile( &Handle, (ACCESS_MASK)FILE_READ_ATTRIBUTES, &Obja, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN_FOR_BACKUP_INTENT ); RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer); if ( !NT_SUCCESS(Status) ) { BaseSetLastNTError(Status); return (DWORD)-1; } // // Get the compressed file size. // Status = NtQueryInformationFile( Handle, &IoStatusBlock, &CompressionInfo, sizeof(CompressionInfo), FileCompressionInformation ); if ( !NT_SUCCESS(Status) ) { FileSizeLow = GetFileSize(Handle,lpFileSizeHigh); NtClose(Handle); return FileSizeLow; } NtClose(Handle); if ( ARGUMENT_PRESENT(lpFileSizeHigh) ) { *lpFileSizeHigh = (DWORD)CompressionInfo.CompressedFileSize.HighPart; } if (CompressionInfo.CompressedFileSize.LowPart == -1 ) { SetLastError(0); } return CompressionInfo.CompressedFileSize.LowPart; }
// Querying the file ID from the file itself static int OnFileIdGetClick(HWND hDlg) { TFileTestData * pData = GetDialogData(hDlg); OBJECT_ATTRIBUTES ObjAttr; IO_STATUS_BLOCK IoStatus; UNICODE_STRING FolderName = {0, 0, NULL}; UNICODE_STRING FileName = {0, 0, NULL}; ULARGE_INTEGER FileId = {0}; NTSTATUS Status = STATUS_SUCCESS; HANDLE Handle = NULL; TCHAR szFileID[MAX_FILEID_PATH]; BYTE InfoBuff[0x200]; // Convert the file name to the NT file name if(NT_SUCCESS(Status)) { SaveDialog(hDlg); Status = FileNameToUnicodeString(&FolderName, pData->szFileName1); } // Get the directory name from the file name if(NT_SUCCESS(Status)) { PWSTR sz = FolderName.Buffer + (FolderName.Length / sizeof(WCHAR)); // Go back and find the last directory name while(sz > FolderName.Buffer && sz[0] != L'\\') sz--; // Did we find it? if(sz[0] == L'\\' && sz > FolderName.Buffer) { // Initialize the file name sz = sz + 1; RtlInitUnicodeString(&FileName, sz); // Cut the folder name. Make sure that the ending backslash is there, // because we don't want to open "\??\C:" instead of "\??\C:\" FolderName.MaximumLength = FolderName.Length = (USHORT)((sz - FolderName.Buffer) * sizeof(WCHAR)); // Attempt to open the folder and query the ID InitializeObjectAttributes(&ObjAttr, &FolderName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&Handle, FILE_READ_DATA | SYNCHRONIZE, &ObjAttr, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT); // If succeeded, we call for query directory on thet file if(NT_SUCCESS(Status)) { PFILE_ID_BOTH_DIR_INFORMATION pDirInfo = (PFILE_ID_BOTH_DIR_INFORMATION)InfoBuff; Status = NtQueryDirectoryFile(Handle, NULL, NULL, NULL, &IoStatus, pDirInfo, sizeof(InfoBuff), FileIdBothDirectoryInformation, TRUE, &FileName, FALSE); if(NT_SUCCESS(Status)) FileId.QuadPart = pDirInfo->FileId.QuadPart; NtClose(Handle); } } else { // Do it by Open - QueryID - Close InitializeObjectAttributes(&ObjAttr, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&Handle, FILE_READ_ATTRIBUTES, &ObjAttr, &IoStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0); if(NT_SUCCESS(Status)) { PFILE_INTERNAL_INFORMATION pFileInfo = (PFILE_INTERNAL_INFORMATION)InfoBuff; Status = NtQueryInformationFile(Handle, &IoStatus, pFileInfo, sizeof(FILE_INTERNAL_INFORMATION), FileInternalInformation); if(NT_SUCCESS(Status)) FileId.QuadPart = pFileInfo->IndexNumber.QuadPart; NtClose(Handle); } } } // Did we query the file ID just fine? if(NT_SUCCESS(Status)) { FileIDToString(pData, FileId.QuadPart, szFileID); SetDlgItemText(hDlg, IDC_FILE_ID, szFileID); } // On the end, set the file ID SetResultInfo(hDlg, RtlNtStatusToDosError(Status)); FreeFileNameString(&FolderName); return TRUE; }
NTSTATUS IniCacheLoad( PINICACHE *Cache, PWCHAR FileName, BOOLEAN String) { UNICODE_STRING Name; OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; PCHAR Ptr; LARGE_INTEGER FileOffset; PINICACHESECTION Section; PINICACHEKEY Key; PCHAR SectionName; ULONG SectionNameSize; PCHAR KeyName; ULONG KeyNameSize; PCHAR KeyValue; ULONG KeyValueSize; *Cache = NULL; /* Open ini file */ RtlInitUnicodeString(&Name, FileName); InitializeObjectAttributes(&ObjectAttributes, &Name, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return Status; } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return Status; } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBuffer = (CHAR*)RtlAllocateHeap(ProcessHeap, 0, FileLength + 1); if (FileBuffer == NULL) { DPRINT1("RtlAllocateHeap() failed\n"); NtClose(FileHandle); return STATUS_INSUFFICIENT_RESOURCES; } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; NtClose(FileHandle); if (!NT_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); RtlFreeHeap(ProcessHeap, 0, FileBuffer); return Status; } /* Allocate inicache header */ *Cache = (PINICACHE)RtlAllocateHeap(ProcessHeap, 0, sizeof(INICACHE)); if (*Cache == NULL) { DPRINT("RtlAllocateHeap() failed\n"); return STATUS_INSUFFICIENT_RESOURCES; } /* Initialize inicache header */ RtlZeroMemory(*Cache, sizeof(INICACHE)); /* Parse ini file */ Section = NULL; Ptr = FileBuffer; while (Ptr != NULL && *Ptr != 0) { Ptr = IniCacheSkipWhitespace(Ptr); if (Ptr == NULL) continue; if (*Ptr == '[') { Section = NULL; Ptr++; Ptr = IniCacheGetSectionName(Ptr, &SectionName, &SectionNameSize); DPRINT1("[%.*s]\n", SectionNameSize, SectionName); Section = IniCacheAddSection(*Cache, SectionName, SectionNameSize); if (Section == NULL) { DPRINT("IniCacheAddSection() failed\n"); Ptr = IniCacheSkipToNextSection(Ptr); continue; } } else { if (Section == NULL) { Ptr = IniCacheSkipToNextSection(Ptr); continue; } Ptr = IniCacheGetKeyName(Ptr, &KeyName, &KeyNameSize); Ptr = IniCacheGetKeyValue(Ptr, &KeyValue, &KeyValueSize, String); DPRINT1("'%.*s' = '%.*s'\n", KeyNameSize, KeyName, KeyValueSize, KeyValue); Key = IniCacheAddKey(Section, KeyName, KeyNameSize, KeyValue, KeyValueSize); if (Key == NULL) { DPRINT("IniCacheAddKey() failed\n"); } } } /* Free file buffer */ RtlFreeHeap(ProcessHeap, 0, FileBuffer); return Status; }
/* * FUNCTION: Extracts a file from the cabinet * ARGUMENTS: * Search = Pointer to PCAB_SEARCH structure used to locate the file * RETURNS * Status of operation */ ULONG CabinetExtractFile(PCAB_SEARCH Search) { ULONG Size; // remaining file bytes to decompress ULONG CurrentOffset; // current uncompressed offset within the folder PUCHAR CurrentBuffer; // current pointer to compressed data in the block LONG RemainingBlock; // remaining comp data in the block HANDLE DestFile; HANDLE DestFileSection; PVOID DestFileBuffer; // mapped view of dest file PVOID CurrentDestBuffer; // pointer to the current position in the dest view PCFDATA CFData; // current data block ULONG Status; FILETIME FileTime; WCHAR DestName[MAX_PATH]; NTSTATUS NtStatus; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; FILE_BASIC_INFORMATION FileBasic; PCFFOLDER CurrentFolder; LARGE_INTEGER MaxDestFileSize; LONG InputLength, OutputLength; char Junk[512]; if (wcscmp(Search->Cabinet, CabinetName) != 0) { /* the file is not in the current cabinet */ DPRINT("File is not in this cabinet (%S != %S)\n", Search->Cabinet, CabinetName); return CAB_STATUS_NOFILE; } /* look up the folder that the file specifies */ if (Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF) { /* folder is continued from previous cabinet, that shouldn't happen here */ return CAB_STATUS_NOFILE; } else if (Search->File->FolderIndex == 0xFFFE) { /* folder is the last in this cabinet and continues into next */ CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1]; } else { /* folder is completely contained within this cabinet */ CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; } switch (CurrentFolder->CompressionType & CAB_COMP_MASK) { case CAB_COMP_NONE: CabinetSelectCodec(CAB_CODEC_RAW); break; case CAB_COMP_MSZIP: CabinetSelectCodec(CAB_CODEC_MSZIP); break; default: return CAB_STATUS_UNSUPPCOMP; } DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n", (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize); RtlInitAnsiString(&AnsiString, Search->File->FileName); wcscpy(DestName, DestPath); UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR); UnicodeString.Buffer = DestName + wcslen(DestName); UnicodeString.Length = 0; RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); /* Create destination file, fail if it already exists */ RtlInitUnicodeString(&UnicodeString, DestName); InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); /* If file exists, ask to overwrite file */ if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) { /* Create destination file, overwrite if it already exists */ NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); return CAB_STATUS_CANNOT_CREATE; } } else { DPRINT("File (%S) exists\n", DestName); return CAB_STATUS_FILE_EXISTS; } } MaxDestFileSize.QuadPart = Search->File->FileSize; NtStatus = NtCreateSection(&DestFileSection, SECTION_ALL_ACCESS, 0, &MaxDestFileSize, PAGE_READWRITE, SEC_COMMIT, DestFile); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFile; } DestFileBuffer = 0; DestFileSize = 0; NtStatus = NtMapViewOfSection(DestFileSection, NtCurrentProcess(), &DestFileBuffer, 0, 0, 0, &DestFileSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFileSection; } CurrentDestBuffer = DestFileBuffer; if (!ConvertDosDateTimeToFileTime(Search->File->FileDate, Search->File->FileTime, &FileTime)) { DPRINT("DosDateTimeToFileTime() failed\n"); Status = CAB_STATUS_CANNOT_WRITE; goto UnmapDestFile; } NtStatus = NtQueryInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); } else { memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME)); NtStatus = NtSetInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); } } SetAttributesOnFile(Search->File, DestFile); /* Call extract event handler */ if (ExtractHandler != NULL) { ExtractHandler(Search->File, DestName); } /* find the starting block of the file start with the first data block of the folder */ CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); CurrentOffset = 0; while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset) { /* walk the data blocks until we reach the one containing the start of the file */ CurrentOffset += CFData->UncompSize; CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize); } /* now decompress and discard any data in the block before the start of the file */ /* start of comp data */ CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved; RemainingBlock = CFData->CompSize; InputLength = RemainingBlock; while (CurrentOffset < Search->File->FileOffset) { /* compute remaining uncomp bytes to start of file, bounded by sizeof junk */ OutputLength = Search->File->FileOffset - CurrentOffset; if (OutputLength > (LONG)sizeof(Junk)) OutputLength = sizeof (Junk); /* negate to signal NOT end of block */ OutputLength = -OutputLength; CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength); /* add the uncomp bytes extracted to current folder offset */ CurrentOffset += OutputLength; /* add comp bytes consumed to CurrentBuffer */ CurrentBuffer += InputLength; /* subtract bytes consumed from bytes remaining in block */ RemainingBlock -= InputLength; /* neg for resume decompression of the same block */ InputLength = -RemainingBlock; } /* now CurrentBuffer points to the first comp byte of the file, so we can begin decompressing */ /* Size = remaining uncomp bytes of the file to decompress */ Size = Search->File->FileSize; while (Size > 0) { OutputLength = Size; DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n", CurrentBuffer, RemainingBlock, Size); Status = CodecUncompress(CurrentDestBuffer, CurrentBuffer, &InputLength, &OutputLength); if (Status != CS_SUCCESS) { DPRINT("Cannot uncompress block\n"); if (Status == CS_NOMEMORY) Status = CAB_STATUS_NOMEMORY; Status = CAB_STATUS_INVALID_CAB; goto UnmapDestFile; } /* advance dest buffer by bytes produced */ CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength); /* advance src buffer by bytes consumed */ CurrentBuffer += InputLength; /* reduce remaining file bytes by bytes produced */ Size -= OutputLength; /* reduce remaining block size by bytes consumed */ RemainingBlock -= InputLength; if (RemainingBlock == 0) { /* used up this block, move on to the next */ DPRINT("Out of block data\n"); CFData = (PCFDATA)CurrentBuffer; RemainingBlock = CFData->CompSize; CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved; InputLength = RemainingBlock; } } Status = CAB_STATUS_SUCCESS; UnmapDestFile: NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer); CloseDestFileSection: NtClose(DestFileSection); CloseDestFile: NtClose(DestFile); return Status; }
NTSTATUS InfOpenFile(PHINF InfHandle, PUNICODE_STRING FileName, PULONG ErrorLine) { OBJECT_ATTRIBUTES ObjectAttributes; FILE_STANDARD_INFORMATION FileInfo; IO_STATUS_BLOCK IoStatusBlock; HANDLE FileHandle; NTSTATUS Status; PCHAR FileBuffer; ULONG FileLength; LARGE_INTEGER FileOffset; PINFCACHE Cache; CheckHeap(); *InfHandle = NULL; *ErrorLine = (ULONG)-1; /* Open the inf file */ InitializeObjectAttributes(&ObjectAttributes, FileName, 0, NULL, NULL); Status = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); if (!INF_SUCCESS(Status)) { DPRINT("NtOpenFile() failed (Status %lx)\n", Status); return(Status); } DPRINT("NtOpenFile() successful\n"); /* Query file size */ Status = NtQueryInformationFile(FileHandle, &IoStatusBlock, &FileInfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!INF_SUCCESS(Status)) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return(Status); } FileLength = FileInfo.EndOfFile.u.LowPart; DPRINT("File size: %lu\n", FileLength); /* Allocate file buffer */ FileBuffer = MALLOC(FileLength + 1); if (FileBuffer == NULL) { DPRINT1("MALLOC() failed\n"); NtClose(FileHandle); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Read file */ FileOffset.QuadPart = 0ULL; Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, FileBuffer, FileLength, &FileOffset, NULL); /* Append string terminator */ FileBuffer[FileLength] = 0; NtClose(FileHandle); if (!INF_SUCCESS(Status)) { DPRINT("NtReadFile() failed (Status %lx)\n", Status); FREE(FileBuffer); return(Status); } /* Allocate infcache header */ Cache = (PINFCACHE)MALLOC(sizeof(INFCACHE)); if (Cache == NULL) { DPRINT("MALLOC() failed\n"); FREE(FileBuffer); return(INF_STATUS_INSUFFICIENT_RESOURCES); } /* Initialize inicache header */ ZEROMEMORY(Cache, sizeof(INFCACHE)); /* Parse the inf buffer */ Status = InfpParseBuffer (Cache, FileBuffer, FileBuffer + FileLength, ErrorLine); if (!INF_SUCCESS(Status)) { FREE(Cache); Cache = NULL; } /* Free file buffer */ FREE(FileBuffer); *InfHandle = (HINF)Cache; return(Status); }
NTSTATUS SetupCopyFile( PWCHAR SourceFileName, PWCHAR DestinationFileName) { OBJECT_ATTRIBUTES ObjectAttributes; HANDLE FileHandleSource; HANDLE FileHandleDest; static IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION FileStandard; FILE_BASIC_INFORMATION FileBasic; ULONG RegionSize; UNICODE_STRING FileName; NTSTATUS Status; PVOID SourceFileMap = 0; HANDLE SourceFileSection; SIZE_T SourceSectionSize = 0; LARGE_INTEGER ByteOffset; #ifdef __REACTOS__ RtlInitUnicodeString(&FileName, SourceFileName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenFile(&FileHandleSource, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SEQUENTIAL_ONLY); if (!NT_SUCCESS(Status)) { DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName); goto done; } #else FileHandleSource = CreateFileW(SourceFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (FileHandleSource == INVALID_HANDLE_VALUE) { Status = STATUS_UNSUCCESSFUL; goto done; } #endif Status = NtQueryInformationFile(FileHandleSource, &IoStatusBlock, &FileStandard, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtQueryInformationFile failed: %x\n", Status); goto closesrc; } Status = NtQueryInformationFile(FileHandleSource, &IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtQueryInformationFile failed: %x\n", Status); goto closesrc; } Status = NtCreateSection(&SourceFileSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, SEC_COMMIT, FileHandleSource); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName); goto closesrc; } Status = NtMapViewOfSection(SourceFileSection, NtCurrentProcess(), &SourceFileMap, 0, 0, NULL, &SourceSectionSize, ViewUnmap, 0, PAGE_READONLY ); if (!NT_SUCCESS(Status)) { DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName); goto closesrcsec; } RtlInitUnicodeString(&FileName, DestinationFileName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile(&FileHandleDest, GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_NO_INTERMEDIATE_BUFFERING | FILE_SEQUENTIAL_ONLY | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateFile failed: %x\n", Status); goto unmapsrcsec; } RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart); IoStatusBlock.Status = 0; ByteOffset.QuadPart = 0; Status = NtWriteFile(FileHandleDest, NULL, NULL, NULL, &IoStatusBlock, SourceFileMap, RegionSize, &ByteOffset, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status, IoStatusBlock.Status, &IoStatusBlock, SourceFileMap, RegionSize); goto closedest; } /* Copy file date/time from source file */ Status = NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetInformationFile failed: %x\n", Status); goto closedest; } /* shorten the file back to it's real size after completing the write */ Status = NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileStandard.EndOfFile, sizeof(FILE_END_OF_FILE_INFORMATION), FileEndOfFileInformation); if (!NT_SUCCESS(Status)) { DPRINT1("NtSetInformationFile failed: %x\n", Status); } closedest: NtClose(FileHandleDest); unmapsrcsec: NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap); closesrcsec: NtClose(SourceFileSection); closesrc: NtClose(FileHandleSource); done: return Status; }
/* * @implemented */ BOOL WINAPI CopyFileExW ( LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, BOOL *pbCancel, DWORD dwCopyFlags ) { NTSTATUS errCode; HANDLE FileHandleSource, FileHandleDest; IO_STATUS_BLOCK IoStatusBlock; FILE_STANDARD_INFORMATION FileStandard; FILE_BASIC_INFORMATION FileBasic; BOOL RC = FALSE; BOOL KeepDestOnError = FALSE; DWORD SystemError; FileHandleSource = CreateFileW(lpExistingFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING, NULL); if (INVALID_HANDLE_VALUE != FileHandleSource) { errCode = NtQueryInformationFile(FileHandleSource, &IoStatusBlock, &FileStandard, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(errCode)) { TRACE("Status 0x%08x obtaining FileStandardInformation for source\n", errCode); BaseSetLastNTError(errCode); } else { errCode = NtQueryInformationFile(FileHandleSource, &IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(errCode)) { TRACE("Status 0x%08x obtaining FileBasicInformation for source\n", errCode); BaseSetLastNTError(errCode); } else { FileHandleDest = CreateFileW(lpNewFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS, FileBasic.FileAttributes, NULL); if (INVALID_HANDLE_VALUE != FileHandleDest) { errCode = CopyLoop(FileHandleSource, FileHandleDest, FileStandard.EndOfFile, lpProgressRoutine, lpData, pbCancel, &KeepDestOnError); if (!NT_SUCCESS(errCode)) { BaseSetLastNTError(errCode); } else { LARGE_INTEGER t; t.QuadPart = FileBasic.LastWriteTime.QuadPart; errCode = SetLastWriteTime(FileHandleDest, t); if (!NT_SUCCESS(errCode)) { BaseSetLastNTError(errCode); } else { RC = TRUE; } } NtClose(FileHandleDest); if (! RC && ! KeepDestOnError) { SystemError = GetLastError(); SetFileAttributesW(lpNewFileName, FILE_ATTRIBUTE_NORMAL); DeleteFileW(lpNewFileName); SetLastError(SystemError); } } else { WARN("Error %d during opening of dest file\n", GetLastError()); } } } NtClose(FileHandleSource); } else { WARN("Error %d during opening of source file\n", GetLastError()); } return RC; }
/*++ * @name SmpMoveFile * * The SmpMoveFile function deletes a specify file. * * @param lpExistingFileName * the name of an existing file which should be removed * * @param lpNewFileName * a new name of an existing file. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL * othwerwise. * * @remarks * This function called from the SmpMoveFilesQueryRoutine function. * * *--*/ NTSTATUS SmpMoveFile( IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName ) { PFILE_RENAME_INFORMATION FileRenameInfo; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING ExistingFileNameU; HANDLE FileHandle; DWORD FileNameSize; BOOLEAN ReplaceIfExists; NTSTATUS Status; if( !lpExistingFileName || !lpNewFileName ) return (STATUS_INVALID_PARAMETER); DPRINT("SmpMoveFile (%S, %S)\n", lpExistingFileName, lpNewFileName); RtlInitUnicodeString(&ExistingFileNameU, lpExistingFileName); InitializeObjectAttributes(&ObjectAttributes, &ExistingFileNameU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile (&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if( !NT_SUCCESS(Status) ) { DPRINT("NtCreateFile() failed (Status %lx)\n", Status); return (Status); } FileNameSize = wcslen(lpNewFileName)*sizeof(*lpNewFileName); FileRenameInfo = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILE_RENAME_INFORMATION)+FileNameSize); if( !FileRenameInfo ) { DPRINT("RtlAllocateHeap failed\n"); NtClose(FileHandle); return (STATUS_NO_MEMORY); } if( L'!' == *lpNewFileName ) { lpNewFileName++; FileNameSize -= sizeof(*lpNewFileName); ReplaceIfExists = TRUE; } else { ReplaceIfExists = FALSE; } FileRenameInfo->RootDirectory = NULL; FileRenameInfo->ReplaceIfExists = ReplaceIfExists; FileRenameInfo->FileNameLength = FileNameSize; RtlCopyMemory(FileRenameInfo->FileName, lpNewFileName, FileNameSize); Status = NtSetInformationFile( FileHandle, &IoStatusBlock, FileRenameInfo, sizeof(FILE_RENAME_INFORMATION)+FileNameSize, FileRenameInformation ); RtlFreeHeap(RtlGetProcessHeap(), 0, FileRenameInfo); /* FIXME: After the FileRenameInformation parameter will be implemented into the fs driver the following code can be removed */ if( STATUS_NOT_IMPLEMENTED == Status ) { HANDLE FileHandleNew; UNICODE_STRING NewFileNameU; FILE_BASIC_INFORMATION FileBasicInfo; UCHAR *lpBuffer = NULL; SIZE_T RegionSize = 0x10000; LARGE_INTEGER BytesCopied; BOOL EndOfFileFound; Status = NtQueryInformationFile( FileHandle, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return (Status); } RtlInitUnicodeString(&NewFileNameU, lpNewFileName); InitializeObjectAttributes(&ObjectAttributes, &NewFileNameU, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtCreateFile (&FileHandleNew, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, ReplaceIfExists ? FILE_OVERWRITE_IF : FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if( !NT_SUCCESS(Status) ) { DPRINT("NtCreateFile() failed (Status %lx)\n", Status); NtClose(FileHandle); return (Status); } Status = NtAllocateVirtualMemory( NtCurrentProcess(), (PVOID *)&lpBuffer, 2, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if( !NT_SUCCESS(Status) ) { DPRINT("NtAllocateVirtualMemory() failed (Status %lx)\n", Status); NtClose(FileHandle); SmpDeleteFile(lpNewFileName); return (Status); } BytesCopied.QuadPart = 0; EndOfFileFound = FALSE; while( !EndOfFileFound && NT_SUCCESS(Status) ) { Status = NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, RegionSize, NULL, NULL); if( NT_SUCCESS(Status) ) { Status = NtWriteFile(FileHandleNew, NULL, NULL, NULL, &IoStatusBlock, lpBuffer, IoStatusBlock.Information, NULL, NULL); if( NT_SUCCESS(Status) ) { BytesCopied.QuadPart += IoStatusBlock.Information; } else { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); } } else { if( STATUS_END_OF_FILE == Status ) { EndOfFileFound = TRUE; Status = STATUS_SUCCESS; } else { DPRINT("NtWriteFile() failed (Status %lx)\n", Status); } } } NtFreeVirtualMemory(NtCurrentProcess(), (PVOID *)&lpBuffer, &RegionSize, MEM_RELEASE); Status = NtQueryInformationFile( FileHandleNew, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status); } Status = NtSetInformationFile(FileHandleNew, &IoStatusBlock, &FileBasicInfo, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if( !NT_SUCCESS(Status) ) { DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status); } NtClose(FileHandleNew); NtClose(FileHandle); SmpDeleteFile(lpExistingFileName); return (Status); } NtClose(FileHandle); return (Status); }
/* * SfuLoadPeerList * * Purpose: * * Load peer list from filename given in win32 format. * */ NTSTATUS SfuLoadPeerList( _In_ OBJECT_ATTRIBUTES *ObjectAttributes, _In_ ZA_PEERINFO **PeerList, _In_ PULONG NumberOfPeers ) { BOOL cond = FALSE; HANDLE hFile = NULL; PVOID pData = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; IO_STATUS_BLOCK iost; FILE_STANDARD_INFORMATION fsi; if ((NumberOfPeers == NULL) || (PeerList == NULL)) return status; do { status = NtOpenFile(&hFile, FILE_READ_ACCESS | SYNCHRONIZE, ObjectAttributes, &iost, FILE_SHARE_READ, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(status)) break; RtlSecureZeroMemory(&fsi, sizeof(fsi)); status = NtQueryInformationFile(hFile, &iost, (PVOID)&fsi, sizeof(fsi), FileStandardInformation); if (!NT_SUCCESS(status)) break; pData = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, (SIZE_T)fsi.EndOfFile.LowPart); if (pData == NULL) { status = STATUS_MEMORY_NOT_ALLOCATED; break; } if ((fsi.EndOfFile.LowPart % sizeof(ZA_PEERINFO)) != 0) {// incomplete/damaged file status = STATUS_BAD_DATA; break; } status = NtReadFile(hFile, NULL, NULL, NULL, &iost, pData, fsi.EndOfFile.LowPart, NULL, NULL); if (NT_SUCCESS(status)) { *NumberOfPeers = (ULONG)(iost.Information / sizeof(ZA_PEERINFO)); *PeerList = pData; } else { RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, pData); *NumberOfPeers = 0; *PeerList = NULL; } } while (cond); if (hFile) NtClose(hFile); return status; }