BOOL WINAPI_DECL GetFileInformationByHandle( _In_ HANDLE hFile, _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation ) { FILE_BASIC_INFO basicInfo; FILE_STANDARD_INFO standardInfo; BOOL b = GetFileInformationByHandleEx( hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)); if (b == FALSE) return FALSE; b = GetFileInformationByHandleEx( hFile, FileStandardInfo, &standardInfo, sizeof(standardInfo)); if (b == FALSE) return FALSE; lpFileInformation->dwFileAttributes = basicInfo.FileAttributes; lpFileInformation->ftCreationTime = (FILETIME const &)basicInfo.CreationTime; lpFileInformation->ftLastAccessTime = (FILETIME const &)basicInfo.LastAccessTime; lpFileInformation->ftLastWriteTime = (FILETIME const &)basicInfo.LastWriteTime; lpFileInformation->dwVolumeSerialNumber = 0; lpFileInformation->nFileSizeHigh = standardInfo.EndOfFile.HighPart; lpFileInformation->nFileSizeLow = standardInfo.EndOfFile.LowPart; lpFileInformation->nNumberOfLinks = standardInfo.NumberOfLinks; lpFileInformation->nFileIndexHigh = 0; lpFileInformation->nFileIndexLow = 0; return TRUE; }
bool fs::file::stat(stat_t& info) const { g_tls_error = fse::ok; #ifdef _WIN32 FILE_BASIC_INFO basic_info; if (!GetFileInformationByHandleEx((HANDLE)m_fd, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))) { return false; } info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = this->size(); info.atime = to_time_t(basic_info.LastAccessTime); info.mtime = to_time_t(basic_info.ChangeTime); info.ctime = to_time_t(basic_info.CreationTime); #else struct stat file_info; if (fstat(m_fd, &file_info) < 0) { return false; } info.is_directory = S_ISDIR(file_info.st_mode); info.is_writable = file_info.st_mode & 0200; // HACK: approximation info.size = file_info.st_size; info.atime = file_info.st_atime; info.mtime = file_info.st_mtime; info.ctime = file_info.st_ctime; #endif return true; }
void File::Touch(StringIn filename, FILETIME fileTime) { #if 0 DWORD creationDisposition = OPEN_ALWAYS; HANDLE hFile = CreateFileW(CStringw(filename), GENERIC_READ | GENERIC_WRITE, 0/*share*/, NULL, creationDisposition, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { IO::StringWriter str; str << "Touch failed for " << filename; raise(IOException(str.str())); } BOOL success; FILE_BASIC_INFO info; success = GetFileInformationByHandleEx(hFile, FileBasicInfo, &info, sizeof(info)); if (!success) { raise_(Exception::FromHResult(HRESULT_FROM_WIN32(GetLastError()))); } info.LastWriteTime.QuadPart = *(uint64*)&fileTime; info.LastAccessTime.QuadPart = *(uint64*)&fileTime; success = SetFileInformationByHandle(hFile, FileBasicInfo, &info, sizeof(info)); if (!success) { raise_(Exception::FromHResult(HRESULT_FROM_WIN32(GetLastError()))); } CloseHandle(hFile); #endif }
int fchmod(int fd, mode_t mode) { HANDLE h = (HANDLE)_get_osfhandle(fd); if (h == INVALID_HANDLE_VALUE) { return -1; } FILE_ATTRIBUTE_TAG_INFO attr{}; if (!GetFileInformationByHandleEx( h, FileAttributeTagInfo, &attr, sizeof(attr))) { return -1; } if (mode & _S_IWRITE) { attr.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; } else { attr.FileAttributes |= FILE_ATTRIBUTE_READONLY; } if (!SetFileInformationByHandle( h, FileAttributeTagInfo, &attr, sizeof(attr))) { return -1; } return 0; }
BOOL WINAPI_DECL SetFileTime( _In_ HANDLE hFile, _In_opt_ const FILETIME *lpCreationTime, _In_opt_ const FILETIME *lpLastAccessTime, _In_opt_ const FILETIME *lpLastWriteTime ) { FILE_BASIC_INFO basicInfo; BOOL b = GetFileInformationByHandleEx( hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)); if (b == FALSE) return FALSE; if (lpCreationTime) basicInfo.CreationTime = *(LARGE_INTEGER const *)lpCreationTime; if (lpLastAccessTime) basicInfo.LastAccessTime = *(LARGE_INTEGER const *)lpLastAccessTime; if (lpLastWriteTime) basicInfo.LastWriteTime = *(LARGE_INTEGER const *)lpLastAccessTime; b = SetFileInformationByHandle( hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)); return b; }
char *Yap_guessFileName(int f, int sno, char *nameb, size_t max) { #if __linux__ char path[256]; if (snprintf(path, 255, "/proc/self/fd/%d", f) && readlink(path, nameb, max)) return nameb; #elif __APPLE__ if (fcntl(f, F_GETPATH, nameb) != -1) { return nameb; } #elif __WIN32_ FILE_NAME_INFO *fni = (FILE_NAME_INFO *)malloc(sizeof(FILE_NAME_INFO) + sizeof(WCHAR) * MAXPATHLEN); HANDLE handle = (HANDLE)_get_osfhandle(f); if (GetFileInformationByHandleEx(handle, FileNameInfo, &fni, max)) { int i; char *ptr = nameb; for (i = 0; i < fni->FileNameLength; i++) *ptr = _PL__utf8_put_char(ptr, fni->FileName[i]); *ptr = '\0'; return nameb; } #endif if (!StreamName(sno)) { return NULL; } return RepAtom(AtomOfTerm(StreamName(sno)))->StrOfAE; }
static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem, PWSTR FileName, PUINT32 PFileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) { PTFS *Ptfs = (PTFS *)FileSystem->UserContext; WCHAR FullPath[FULLPATH_SIZE]; HANDLE Handle; FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo; DWORD SecurityDescriptorSizeNeeded; NTSTATUS Result; if (!ConcatPath(Ptfs, FileName, FullPath)) return STATUS_OBJECT_NAME_INVALID; Handle = CreateFileW(FullPath, FILE_READ_ATTRIBUTES | READ_CONTROL, 0, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if (INVALID_HANDLE_VALUE == Handle) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } if (0 != PFileAttributes) { if (!GetFileInformationByHandleEx(Handle, FileAttributeTagInfo, &AttributeTagInfo, sizeof AttributeTagInfo)) { Result = FspNtStatusFromWin32(GetLastError()); goto exit; } *PFileAttributes = AttributeTagInfo.FileAttributes; } if (0 != PSecurityDescriptorSize) { if (!GetKernelObjectSecurity(Handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, SecurityDescriptor, (DWORD)*PSecurityDescriptorSize, &SecurityDescriptorSizeNeeded)) { *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; Result = FspNtStatusFromWin32(GetLastError()); goto exit; } *PSecurityDescriptorSize = SecurityDescriptorSizeNeeded; } Result = STATUS_SUCCESS; exit: if (INVALID_HANDLE_VALUE != Handle) CloseHandle(Handle); return Result; }
INT_PTR CALLBACK fsi_WindowHandler(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static FILE_STANDARD_INFO fsi; static HANDLE hFile = nullptr; switch ( uMsg ) { case WM_INITDIALOG: { RtlZeroMemory(&fsi, sizeof(fsi)); return TRUE; } case WM_SETFILE_HANDLE: { BOOL bClear; hFile = (HANDLE)lParam; if ( hFile && hFile != INVALID_HANDLE_VALUE ) { BOOL bResult; bClear = FALSE; bResult = GetFileInformationByHandleEx(hFile, FileStandardInfo, &fsi, sizeof(fsi)); if ( bResult ) { LPTSTR lpMsg; DWORD dwMsgSize; dwMsgSize = 1024 * sizeof(TCHAR); lpMsg = (LPTSTR)LocalAlloc(LPTR, dwMsgSize); StringCchPrintf( lpMsg, dwMsgSize, TEXT("%lld"), fsi.AllocationSize.QuadPart ); SetDlgItemText( hDlg, IDC_ALLOCATED_SIZE, lpMsg ); StringCchPrintf( lpMsg, dwMsgSize, TEXT("%lld"), fsi.EndOfFile.QuadPart ); SetDlgItemText( hDlg, IDC_ENDOF_FILE, lpMsg ); LocalFree(lpMsg); SetDlgItemInt(hDlg, IDC_NUMBER_OF_LINKS, fsi.NumberOfLinks, FALSE ); CheckDlgButton( hDlg, IDC_IS_DIRECTORY, fsi.Directory ? BST_CHECKED : BST_UNCHECKED ); CheckDlgButton( hDlg, IDC_DELETED_PENDING, fsi.DeletePending ? BST_CHECKED : BST_UNCHECKED ); } else { bClear = TRUE; } } else { bClear = TRUE; } if ( bClear ) { SetDlgItemInt( hDlg, IDC_ALLOCATED_SIZE, 0, FALSE ); SetDlgItemInt( hDlg, IDC_ENDOF_FILE, 0, FALSE ); SetDlgItemInt( hDlg, IDC_NUMBER_OF_LINKS, 0, FALSE ); CheckDlgButton( hDlg, IDC_IS_DIRECTORY, BST_UNCHECKED ); CheckDlgButton( hDlg, IDC_DELETED_PENDING, BST_UNCHECKED ); } break; } case WM_RESETFILE_HANDLE: { hFile = nullptr; break; } } return FALSE; }
FileInformation FileDescriptor::getInfo() const { #ifndef _WIN32 struct stat st; if (fstat(fd_, &st)) { int err = errno; throw std::system_error(err, std::generic_category(), "fstat"); } return FileInformation(st); #else // _WIN32 FILE_BASIC_INFO binfo; FILE_STANDARD_INFO sinfo; if (!GetFileInformationByHandleEx( (HANDLE)handle(), FileBasicInfo, &binfo, sizeof(binfo))) { throw std::system_error( GetLastError(), std::system_category(), "GetFileInformationByHandleEx FileBasicInfo"); } FileInformation info(binfo.FileAttributes); FILETIME_LARGE_INTEGER_to_timespec(binfo.CreationTime, &info.ctime); FILETIME_LARGE_INTEGER_to_timespec(binfo.LastAccessTime, &info.atime); FILETIME_LARGE_INTEGER_to_timespec(binfo.LastWriteTime, &info.mtime); if (!GetFileInformationByHandleEx( (HANDLE)handle(), FileStandardInfo, &sinfo, sizeof(sinfo))) { throw std::system_error( GetLastError(), std::system_category(), "GetFileInformationByHandleEx FileStandardInfo"); } info.size = sinfo.EndOfFile.QuadPart; info.nlink = sinfo.NumberOfLinks; return info; #endif }
LWS_VISIBLE lws_fop_fd_t _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, const char *vpath, lws_fop_flags_t *flags) { HANDLE ret; WCHAR buf[MAX_PATH]; lws_fop_fd_t fop_fd; FILE_STANDARD_INFO fInfo = {0}; MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, LWS_ARRAY_SIZE(buf)); #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 // Windows 8 (minimum when UWP_ENABLED, but can be used in Windows builds) CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; if (((*flags) & 7) == _O_RDONLY) { ret = CreateFile2(buf, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extParams); } else { ret = CreateFile2(buf, GENERIC_WRITE, 0, CREATE_ALWAYS, &extParams); } #else if (((*flags) & 7) == _O_RDONLY) { ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } else { ret = CreateFileW(buf, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } #endif if (ret == LWS_INVALID_FILE) goto bail; fop_fd = malloc(sizeof(*fop_fd)); if (!fop_fd) goto bail; fop_fd->fops = fops; fop_fd->fd = ret; fop_fd->filesystem_priv = NULL; /* we don't use it */ fop_fd->flags = *flags; fop_fd->len = 0; if(GetFileInformationByHandleEx(ret, FileStandardInfo, &fInfo, sizeof(fInfo))) fop_fd->len = fInfo.EndOfFile.QuadPart; fop_fd->pos = 0; return fop_fd; bail: return NULL; }
static void* open_handle (void *handle, const gunichar2 *mapName, gint mapName_length, int mode, gint64 *capacity, int access, int options, int *ioerror, MonoError *error) { g_assert (handle != NULL); // INVALID_HANDLE_VALUE (-1) is valid, to make named shared memory, // backed by physical memory / pagefile. if (handle == INVALID_HANDLE_VALUE) { if (*capacity <= 0 && mode != FILE_MODE_OPEN) { *ioerror = CAPACITY_MUST_BE_POSITIVE; return NULL; } #if SIZEOF_VOID_P == 4 if (*capacity > UINT32_MAX) { *ioerror = CAPACITY_LARGER_THAN_LOGICAL_ADDRESS_SPACE; return NULL; } #endif if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) { *ioerror = INVALID_FILE_MODE; return NULL; } } else { FILE_STANDARD_INFO info; if (!GetFileInformationByHandleEx (handle, FileStandardInfo, &info, sizeof (FILE_STANDARD_INFO))) { *ioerror = convert_win32_error (GetLastError (), COULD_NOT_OPEN); return NULL; } if (*capacity == 0) { if (info.EndOfFile.QuadPart == 0) { *ioerror = CAPACITY_SMALLER_THAN_FILE_SIZE; return NULL; } } else if (*capacity < info.EndOfFile.QuadPart) { *ioerror = CAPACITY_SMALLER_THAN_FILE_SIZE; return NULL; } } HANDLE result = NULL; if (mode == FILE_MODE_CREATE_NEW || handle != INVALID_HANDLE_VALUE) { result = CreateFileMappingW (handle, NULL, get_page_access (access) | options, (DWORD)(((guint64)*capacity) >> 32), (DWORD)*capacity, mapName); if (result && GetLastError () == ERROR_ALREADY_EXISTS) { CloseHandle (result); result = NULL; *ioerror = FILE_ALREADY_EXISTS; } else if (!result && GetLastError () != NO_ERROR) { *ioerror = convert_win32_error (GetLastError (), COULD_NOT_OPEN); } } else if (mode == FILE_MODE_OPEN || mode == FILE_MODE_OPEN_OR_CREATE && access == MMAP_FILE_ACCESS_WRITE) {
static LPTSTR CALLBACK private_GetStreamName(HANDLE hFile, LPCTSTR pPrefix) { FILE_NAME_INFO fni; RtlZeroMemory(&fni, sizeof(fni)); if ( GetFileInformationByHandleEx( hFile, FileNameInfo, &fni, sizeof(fni)) ) { DWORD dwFileName = fni.FileNameLength * sizeof(TCHAR) + 40 + lstrlen(pPrefix); LPTSTR lpstrFileName = (LPTSTR)LocalAlloc(LPTR, dwFileName); StringCchCopy(lpstrFileName, dwFileName, fni.FileName); StringCchCat( lpstrFileName, dwFileName, pPrefix); return lpstrFileName; } return nullptr; }
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque) { HANDLE Handle = ((WinApiFile *)opaque)->handle; PHYSFS_sint64 retval; FILE_STANDARD_INFO file_info = { 0 }; const BOOL res = GetFileInformationByHandleEx(Handle, FileStandardInfo, &file_info, sizeof(file_info)); if (res) { retval = file_info.EndOfFile.QuadPart; assert(retval >= 0); } return retval; } /* __PHYSFS_platformFileLength */
DWORD WINAPI_DECL GetFileSize( _In_ HANDLE hFile, _Out_opt_ LPDWORD lpFileSizeHigh ) { FILE_STANDARD_INFO standardInfo; BOOL b = GetFileInformationByHandleEx( hFile, FileStandardInfo, &standardInfo, sizeof(standardInfo)); if (b == FALSE) return INVALID_FILE_SIZE; return standardInfo.EndOfFile.LowPart; }
BOOL WINAPI_DECL GetFileSizeEx( _In_ HANDLE hFile, _Out_ PLARGE_INTEGER lpFileSize ) { FILE_STANDARD_INFO standardInfo; BOOL b = GetFileInformationByHandleEx( hFile, FileStandardInfo, &standardInfo, sizeof(standardInfo)); if (b == FALSE) return FALSE; *lpFileSize = standardInfo.EndOfFile; return TRUE; }
stat_t stat() override { FILE_BASIC_INFO basic_info; if (!GetFileInformationByHandleEx(m_handle, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))) { throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } stat_t info; info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = this->size(); info.atime = to_time(basic_info.LastAccessTime); info.mtime = to_time(basic_info.ChangeTime); info.ctime = to_time(basic_info.CreationTime); return info; }
size_t ff::GetFileSize(HANDLE hFile) { assertRetVal(hFile, 0); FILE_STANDARD_INFO info; if (GetFileInformationByHandleEx(hFile, FileStandardInfo, &info, sizeof(info))) { #ifdef _WIN64 return info.EndOfFile.QuadPart; #else assert(!info.EndOfFile.HighPart); return info.EndOfFile.HighPart ? 0 : info.EndOfFile.LowPart; #endif } assert(false); return 0; }
/* * print_file_size -- prints file size and its size on disk */ static void print_file_size(const char *filename) { LARGE_INTEGER filesize; FILE_COMPRESSION_INFO fci; HANDLE fh = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fh == INVALID_HANDLE_VALUE) { out_err("CreateFile"); return; } BOOL ret = GetFileSizeEx(fh, &filesize); if (ret == FALSE) { out_err("GetFileSizeEx"); goto err; } ret = GetFileInformationByHandleEx(fh, FileCompressionInfo, &fci, sizeof(fci)); if (ret == FALSE) { out_err("GetFileInformationByHandleEx"); goto err; } if (filesize.QuadPart < 65536) fprintf(stderr, "\ntotal size: %lluB", filesize.QuadPart); else fprintf(stderr, "\ntotal size: %lluKB", filesize.QuadPart / 1024); if (fci.CompressedFileSize.QuadPart < 65536) fprintf(stderr, ", actual size on disk: %lluKB\n", fci.CompressedFileSize.QuadPart); else fprintf(stderr, ", actual size on disk: %lluKB\n", fci.CompressedFileSize.QuadPart / 1024); err: CloseHandle(fh); }
static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem, PVOID FileContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, FSP_FSCTL_FILE_INFO *FileInfo) { HANDLE Handle = HandleFromContext(FileContext); FILE_BASIC_INFO BasicInfo = { 0 }; FILE_ALLOCATION_INFO AllocationInfo = { 0 }; FILE_ATTRIBUTE_TAG_INFO AttributeTagInfo; if (ReplaceFileAttributes) { if (0 == FileAttributes) FileAttributes = FILE_ATTRIBUTE_NORMAL; BasicInfo.FileAttributes = FileAttributes; if (!SetFileInformationByHandle(Handle, FileBasicInfo, &BasicInfo, sizeof BasicInfo)) return FspNtStatusFromWin32(GetLastError()); } else if (0 != FileAttributes) { if (!GetFileInformationByHandleEx(Handle, FileAttributeTagInfo, &AttributeTagInfo, sizeof AttributeTagInfo)) return FspNtStatusFromWin32(GetLastError()); BasicInfo.FileAttributes = FileAttributes | AttributeTagInfo.FileAttributes; if (BasicInfo.FileAttributes ^ FileAttributes) { if (!SetFileInformationByHandle(Handle, FileBasicInfo, &BasicInfo, sizeof BasicInfo)) return FspNtStatusFromWin32(GetLastError()); } } if (!SetFileInformationByHandle(Handle, FileAllocationInfo, &AllocationInfo, sizeof AllocationInfo)) return FspNtStatusFromWin32(GetLastError()); return GetFileInfoInternal(Handle, FileInfo); }
BOOL WINAPI_DECL GetFileTime( _In_ HANDLE hFile, _Out_opt_ LPFILETIME lpCreationTime, _Out_opt_ LPFILETIME lpLastAccessTime, _Out_opt_ LPFILETIME lpLastWriteTime ) { FILE_BASIC_INFO basicInfo; BOOL b = GetFileInformationByHandleEx( hFile, FileBasicInfo, &basicInfo, sizeof(basicInfo)); if (b == FALSE) return FALSE; if (lpCreationTime) *lpCreationTime = (FILETIME const &)basicInfo.CreationTime; if (lpLastAccessTime) *lpLastAccessTime = (FILETIME const &)basicInfo.LastAccessTime; if (lpLastWriteTime) *lpLastWriteTime = (FILETIME const &)basicInfo.LastWriteTime; return TRUE; }
SourceFile* SourceFile::Create( DWORD_PTR ModuleToken, wstring& ModuleName, wstring& FileName ) { BOOL Success; FILE_STANDARD_INFO Info; LPCWSTR Path = FileName.c_str(); HANDLE FileMappingHandle; PVOID Data; PVOID Buffer; DWORD FileSize; HANDLE FileHandle; FileHandle = CreateFile( Path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL ); if (FileHandle == INVALID_HANDLE_VALUE) { return NULL; } Success = GetFileInformationByHandleEx( FileHandle, (FILE_INFO_BY_HANDLE_CLASS)FileStandardInfo, &Info, sizeof(Info) ); if (!Success) { CloseHandle(FileHandle); return NULL; } // Don't support source files greater than 2GB. if (Info.EndOfFile.HighPart != 0) { CloseHandle(FileHandle); return NULL; } FileSize = Info.EndOfFile.LowPart; FileMappingHandle = CreateFileMapping( FileHandle, NULL, PAGE_READONLY, 0, 0, NULL ); if (FileMappingHandle == INVALID_HANDLE_VALUE) { CloseHandle(FileHandle); return NULL; } Data = MapViewOfFile(FileMappingHandle, FILE_MAP_READ, 0, 0, 0); if (Data == NULL) { CloseHandle(FileMappingHandle); CloseHandle(FileHandle); return NULL; } Buffer = VirtualAlloc(0, FileSize, MEM_COMMIT, PAGE_READWRITE); if (Buffer == NULL) { UnmapViewOfFile(Data); CloseHandle(FileMappingHandle); CloseHandle(FileHandle); return NULL; } PCHAR Source = (PCHAR)Data; PCHAR Dest = (PCHAR)Buffer; DWORD Lines = 0; DWORD NextLine = 0; DWORD InitialSize = (FileSize >= 30 ? FileSize / 30 : 3); vector<DWORD> LineOffsets(InitialSize); // LineOffsets[0] = 0 -> dummy entry. // LineOffsets[1] = 0 -> byte offset of first line will always be 0. LineOffsets[Lines++] = 0; LineOffsets[Lines++] = 0; // Copy the file contents from Source to Dest, converting \r and \n // to \0 as we go (allowing the underlying buffer to be cast as a // NUL-terminated C string). for (DWORD i = 0; i < FileSize; i++) { CHAR c = Source[i]; if (c == '\r') { Dest[i] = 0; continue; } else if (c == '\n') { NextLine = i + 1; Dest[i] = 0; } else { Dest[i] = Source[i]; continue; } if (Lines == LineOffsets.size()) { LineOffsets.resize(LineOffsets.size() + 100); } LineOffsets[Lines++] = i + 1; } LineOffsets.resize(Lines); UnmapViewOfFile(Data); CloseHandle(FileMappingHandle); CloseHandle(FileHandle); SourceFile *pSourceFile = new SourceFile( ModuleToken, ModuleName, FileName, FileSize, (PCHAR)Buffer, Lines, LineOffsets ); return pSourceFile; }
JNIEXPORT jint JNICALL Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) { CONSOLE_SCREEN_BUFFER_INFO console_info; HANDLE handle = getHandle(env, output, result); if (handle == NULL) { return CONSOLE_NONE; } #ifndef WINDOWS_MIN // Cygwin/msys console detection, uses an API not available on older Windows versions // Look for a named pipe at the output or input handle, with a specific name: // Cygwin: \cygwin-xxxx-from-master (stdin) // Cygwin: \cygwin-xxxx-to-master (stdout/stderr) // Msys: \msys-xxxx-from-master (stdin) // Msys: \msys-xxxx-to-master (stdout/stderr) DWORD type = GetFileType(handle); if (type == FILE_TYPE_PIPE) { size_t size = sizeof(_FILE_NAME_INFO) + MAX_PATH*sizeof(WCHAR); _FILE_NAME_INFO* name_info = (_FILE_NAME_INFO*)malloc(size); if (GetFileInformationByHandleEx(handle, FileNameInfo, name_info, size) == 0) { mark_failed_with_errno(env, "could not get handle file information", result); free(name_info); return CONSOLE_NONE; } ((char*)name_info->FileName)[name_info->FileNameLength] = 0; int consoleType = CONSOLE_NONE; if (wcsstr(name_info->FileName, L"\\cygwin-") == name_info->FileName || wcsstr(name_info->FileName, L"\\msys-") == name_info->FileName) { if (output == STDIN_DESCRIPTOR) { if (wcsstr(name_info->FileName, L"-from-master") != NULL) { consoleType = CONSOLE_CYGWIN; } } else { if (wcsstr(name_info->FileName, L"-to-master") != NULL) { consoleType = CONSOLE_CYGWIN; } } } free(name_info); return consoleType; } #endif // Else, no Cygwin console detection if (output == STDIN_DESCRIPTOR) { DWORD mode; if (!GetConsoleMode(handle, &mode)) { if (GetLastError() != ERROR_INVALID_HANDLE) { mark_failed_with_errno(env, "could not get console buffer", result); } return CONSOLE_NONE; } return CONSOLE_WINDOWS; } if (!GetConsoleScreenBufferInfo(handle, &console_info)) { if (GetLastError() != ERROR_INVALID_HANDLE) { mark_failed_with_errno(env, "could not get console buffer", result); } return CONSOLE_NONE; } return CONSOLE_WINDOWS; }
void Directory::read() const { #if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_DESKTOP) WIN32_FIND_DATA f; auto pattern = m_path + '*'; auto wpattern = charset::ToWide( pattern.c_str() ); auto h = FindFirstFile( wpattern.get(), &f ); if ( h == INVALID_HANDLE_VALUE ) { LOG_ERROR( "Failed to browse ", m_path ); throw std::system_error( GetLastError(), std::generic_category(), "Failed to browse through directory" ); } do { auto file = charset::FromWide( f.cFileName ); if ( file[0] == '.' && strcasecmp( file.get(), ".nomedia" ) ) continue; auto fullpath = m_path + file.get(); try { if ( ( f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 ) m_dirs.emplace_back( m_fsFactory.createDirectory( m_mrl + utils::url::encode( file.get() ) ) ); else m_files.emplace_back( std::make_shared<File>( fullpath ) ); } catch ( const std::system_error& ex ) { LOG_WARN( "Failed to access a listed file/dir: ", ex.what() , ". Ignoring this entry." ); } } while ( FindNextFile( h, &f ) != 0 ); FindClose( h ); #else // We must remove the trailing / // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx // «Do not use a trailing backslash (\), which indicates the root directory of a drive» auto tmpPath = m_path.substr( 0, m_path.length() - 1 ); auto wpath = charset::ToWide( tmpPath.c_str() ); CREATEFILE2_EXTENDED_PARAMETERS params{}; params.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS; auto handle = CreateFile2( wpath.get(), GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, ¶ms ); if ( handle == INVALID_HANDLE_VALUE ) { LOG_ERROR( "Failed to open directory ", m_path ); throw std::system_error( GetLastError(), std::generic_category(), "Failed to open directory" ); } std::unique_ptr<typename std::remove_pointer<HANDLE>::type, decltype(&CloseHandle)> handlePtr( handle, &CloseHandle ); // Allocating a 32 bytes buffer to contain the file name. If more is required, we'll allocate size_t buffSize = sizeof( FILE_FULL_DIR_INFO ) + 32; std::unique_ptr<FILE_FULL_DIR_INFO, void(*)(FILE_FULL_DIR_INFO*)> dirInfo( reinterpret_cast<FILE_FULL_DIR_INFO*>( malloc( buffSize ) ), [](FILE_FULL_DIR_INFO* ptr) { free( ptr ); } ); if ( dirInfo == nullptr ) throw std::bad_alloc(); while ( true ) { auto h = GetFileInformationByHandleEx( handle, FileFullDirectoryInfo, dirInfo.get(), buffSize ); if ( h == 0 ) { auto error = GetLastError(); if ( error == ERROR_FILE_NOT_FOUND ) break; else if ( error == ERROR_MORE_DATA ) { buffSize *= 2; dirInfo.reset( reinterpret_cast<FILE_FULL_DIR_INFO*>( malloc( buffSize ) ) ); if ( dirInfo == nullptr ) throw std::bad_alloc(); continue; } LOG_ERROR( "Failed to browse ", m_path, ". GetLastError(): ", GetLastError() ); throw std::system_error( GetLastError(), std::generic_category(), "Failed to browse through directory" ); } auto file = charset::FromWide( dirInfo->FileName ); if ( file[0] == '.' && strcasecmp( file.get(), ".nomedia" ) ) continue; try { if ( ( dirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 ) m_dirs.emplace_back( m_fsFactory.createDirectory( m_path + utils::url::encode( file.get() ) ) ); else m_files.emplace_back( std::make_shared<File>( m_path + file.get()) ); } catch ( const std::system_error& ex ) { LOG_WARN( "Failed to access a listed file/dir: ", ex.what() , ". Ignoring this entry." ); } } #endif }
static int winfs_open(const char *pathname, int flags, int mode, struct file **fp, char *target, int buflen) { /* TODO: mode */ DWORD desiredAccess, shareMode, creationDisposition; HANDLE handle; FILE_ATTRIBUTE_TAG_INFO attributeInfo; WCHAR wpathname[PATH_MAX]; struct winfs_file *file; int pathlen = strlen(pathname); if (utf8_to_utf16_filename(pathname, pathlen + 1, wpathname, PATH_MAX) <= 0) return -ENOENT; if (wpathname[0] == 0) { /* CreateFile() does not accept empty filename. */ wpathname[0] = '.'; wpathname[1] = 0; } if (flags & O_PATH) desiredAccess = 0; else if (flags & O_RDWR) desiredAccess = GENERIC_READ | GENERIC_WRITE; else if (flags & O_WRONLY) desiredAccess = GENERIC_WRITE; else desiredAccess = GENERIC_READ; if (flags & __O_DELETE) desiredAccess |= DELETE; shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; creationDisposition; if (flags & O_EXCL) creationDisposition = CREATE_NEW; else if (flags & O_CREAT) creationDisposition = OPEN_ALWAYS; else creationDisposition = OPEN_EXISTING; //log_debug("CreateFileW(): %s\n", pathname); SECURITY_ATTRIBUTES attr; attr.nLength = sizeof(SECURITY_ATTRIBUTES); attr.lpSecurityDescriptor = NULL; attr.bInheritHandle = (fp != NULL); handle = CreateFileW(wpathname, desiredAccess, shareMode, &attr, creationDisposition, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err == ERROR_FILE_EXISTS || err == ERROR_ALREADY_EXISTS) { log_warning("File already exists.\n"); return -EEXIST; } else { log_warning("Unhandled CreateFileW() failure, error code: %d, returning ENOENT.\n", GetLastError()); return -ENOENT; } } if (!GetFileInformationByHandleEx(handle, FileAttributeTagInfo, &attributeInfo, sizeof(attributeInfo))) { CloseHandle(handle); return -EIO; } /* Test if the file is a symlink */ int is_symlink = 0; if (attributeInfo.FileAttributes != INVALID_FILE_ATTRIBUTES && (attributeInfo.FileAttributes & FILE_ATTRIBUTE_SYSTEM)) { log_info("The file has system flag set.\n"); if (!(desiredAccess & GENERIC_READ)) { /* We need to get a readable handle */ log_info("But the handle does not have READ access, try reopening file...\n"); HANDLE read_handle = ReOpenFile(handle, desiredAccess | GENERIC_READ, shareMode, FILE_FLAG_BACKUP_SEMANTICS); if (read_handle == INVALID_HANDLE_VALUE) { log_warning("Reopen file failed, error code %d. Assume not symlink.\n", GetLastError()); goto after_symlink_test; } CloseHandle(handle); log_info("Reopen succeeded.\n"); handle = read_handle; } if (winfs_read_symlink(handle, target, buflen) > 0) { if (!(flags & O_NOFOLLOW)) { CloseHandle(handle); return 1; } if (!(flags & O_PATH)) { CloseHandle(handle); log_info("Specified O_NOFOLLOW but not O_PATH, returning ELOOP.\n"); return -ELOOP; } is_symlink = 1; } log_info("Opening file directly.\n"); } else if (attributeInfo.FileAttributes != INVALID_FILE_ATTRIBUTES && !(attributeInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (flags & O_DIRECTORY)) { log_warning("Not a directory.\n"); return -ENOTDIR; } after_symlink_test: if (!is_symlink && (flags & O_TRUNC) && ((flags & O_WRONLY) || (flags & O_RDWR))) { /* Truncate the file */ FILE_END_OF_FILE_INFORMATION info; info.EndOfFile.QuadPart = 0; IO_STATUS_BLOCK status_block; NTSTATUS status = NtSetInformationFile(handle, &status_block, &info, sizeof(info), FileEndOfFileInformation); if (!NT_SUCCESS(status)) log_error("NtSetInformationFile() failed, status: %x\n", status); } if (fp) { file = (struct winfs_file *)kmalloc(sizeof(struct winfs_file) + pathlen); file->base_file.op_vtable = &winfs_ops; file->base_file.ref = 1; file->base_file.flags = flags; file->handle = handle; file->restart_scan = 1; file->pathlen = pathlen; memcpy(file->pathname, pathname, pathlen); *fp = (struct file *)file; } else CloseHandle(handle); return 0; }
static int _g_win32_stat_utf16_no_trailing_slashes (const gunichar2 *filename, int fd, GWin32PrivateStat *buf, gboolean for_symlink) { HANDLE file_handle; gboolean succeeded_so_far; DWORD error_code; struct __stat64 statbuf; BY_HANDLE_FILE_INFORMATION handle_info; FILE_STANDARD_INFO std_info; WIN32_FIND_DATAW finddata; DWORD immediate_attributes; gboolean is_symlink = FALSE; gboolean is_directory; DWORD open_flags; wchar_t *filename_target = NULL; int result; if (fd < 0) { immediate_attributes = GetFileAttributesW (filename); if (immediate_attributes == INVALID_FILE_ATTRIBUTES) { error_code = GetLastError (); errno = w32_error_to_errno (error_code); return -1; } is_symlink = (immediate_attributes & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT; is_directory = (immediate_attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; open_flags = FILE_ATTRIBUTE_NORMAL; if (for_symlink && is_symlink) open_flags |= FILE_FLAG_OPEN_REPARSE_POINT; if (is_directory) open_flags |= FILE_FLAG_BACKUP_SEMANTICS; file_handle = CreateFileW (filename, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, open_flags, NULL); if (file_handle == INVALID_HANDLE_VALUE) { error_code = GetLastError (); errno = w32_error_to_errno (error_code); return -1; } } else { file_handle = (HANDLE) _get_osfhandle (fd); if (file_handle == INVALID_HANDLE_VALUE) return -1; } succeeded_so_far = GetFileInformationByHandle (file_handle, &handle_info); error_code = GetLastError (); if (succeeded_so_far) { succeeded_so_far = GetFileInformationByHandleEx (file_handle, FileStandardInfo, &std_info, sizeof (std_info)); error_code = GetLastError (); } if (!succeeded_so_far) { if (fd < 0) CloseHandle (file_handle); errno = w32_error_to_errno (error_code); return -1; } /* It's tempting to use GetFileInformationByHandleEx(FileAttributeTagInfo), * but it always reports that the ReparseTag is 0. */ if (fd < 0) { memset (&finddata, 0, sizeof (finddata)); if (handle_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { HANDLE tmp = FindFirstFileW (filename, &finddata); if (tmp == INVALID_HANDLE_VALUE) { error_code = GetLastError (); errno = w32_error_to_errno (error_code); CloseHandle (file_handle); return -1; } FindClose (tmp); } if (is_symlink && !for_symlink) { /* If filename is a symlink, but we need the target. * To get information about the target we need to resolve * the symlink first. */ DWORD filename_target_len; DWORD new_len; /* Just in case, give it a real memory location instead of NULL */ new_len = GetFinalPathNameByHandleW (file_handle, (wchar_t *) &filename_target_len, 0, FILE_NAME_NORMALIZED); #define SANE_LIMIT 1024 * 10 if (new_len >= SANE_LIMIT) #undef SANE_LIMIT { new_len = 0; error_code = ERROR_BUFFER_OVERFLOW; } else if (new_len == 0) { error_code = GetLastError (); } if (new_len > 0) { /* Pretend that new_len doesn't count the terminating NUL char, * and ask for a bit more space than is needed, and allocate even more. */ filename_target_len = new_len + 3; filename_target = g_malloc ((filename_target_len + 1) * sizeof (wchar_t)); new_len = GetFinalPathNameByHandleW (file_handle, filename_target, filename_target_len, FILE_NAME_NORMALIZED); /* filename_target_len is already larger than needed, * new_len should be smaller than that, even if the size * is off by 1 for some reason. */ if (new_len >= filename_target_len - 1) { new_len = 0; error_code = ERROR_BUFFER_OVERFLOW; g_clear_pointer (&filename_target, g_free); } else if (new_len == 0) { g_clear_pointer (&filename_target, g_free); } /* GetFinalPathNameByHandle() is documented to return extended paths, * strip the extended prefix, if it is followed by a drive letter * and a colon. Otherwise keep it (the path could be * \\\\?\\Volume{GUID}\\ - it's only usable in extended form). */ else if (new_len > 0) { gsize len = new_len; /* Account for NUL-terminator maybe not being counted. * This is why we overallocated earlier. */ if (filename_target[len] != L'\0') { len++; filename_target[len] = L'\0'; } _g_win32_strip_extended_ntobjm_prefix (filename_target, &len); new_len = len; } } if (new_len == 0) succeeded_so_far = FALSE; } CloseHandle (file_handle); } /* else if fd >= 0 the file_handle was obtained via _get_osfhandle() * and must not be closed, it is owned by fd. */ if (!succeeded_so_far) { errno = w32_error_to_errno (error_code); return -1; } /* * We can't use _wstat64() here, because with UCRT it now gives * information about the target, even if we want information about * the link itself (unlike MSVCRT, which gave information about * the link, and if we needed information about the target we were * able to resolve it by ourselves prior to calling _wstat64()). */ if (fd < 0) result = _g_win32_fill_statbuf_from_handle_info (filename, filename_target, &handle_info, &statbuf); else result = _fstat64 (fd, &statbuf); if (result != 0) { int errsv = errno; g_free (filename_target); errno = errsv; return -1; } g_free (filename_target); buf->st_dev = statbuf.st_dev; buf->st_mode = statbuf.st_mode; buf->volume_serial = handle_info.dwVolumeSerialNumber; buf->file_index = (((guint64) handle_info.nFileIndexHigh) << 32) | handle_info.nFileIndexLow; /* Note that immediate_attributes is for the symlink * (if it's a symlink), while handle_info contains info * about the symlink or the target, depending on the flags * we used earlier. */ buf->attributes = handle_info.dwFileAttributes; buf->st_nlink = handle_info.nNumberOfLinks; buf->st_size = (((guint64) handle_info.nFileSizeHigh) << 32) | handle_info.nFileSizeLow; buf->allocated_size = std_info.AllocationSize.QuadPart; if (fd < 0 && buf->attributes & FILE_ATTRIBUTE_REPARSE_POINT) buf->reparse_tag = finddata.dwReserved0; else buf->reparse_tag = 0; buf->st_ctime = statbuf.st_ctime; buf->st_atime = statbuf.st_atime; buf->st_mtime = statbuf.st_mtime; return 0; }
int lstat(const char *path, struct stat *st) { FILE_BASIC_INFO binfo; FILE_STANDARD_INFO sinfo; WCHAR *wpath = w_utf8_to_win_unc(path, -1); HANDLE h; DWORD err; memset(st, 0, sizeof(*st)); if (!wpath) { return -1; } h = CreateFileW(wpath, FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); err = GetLastError(); free(wpath); if (h == INVALID_HANDLE_VALUE) { w_log(W_LOG_DBG, "lstat(%s): %s\n", path, win32_strerror(err)); errno = map_win32_err(err); return -1; } if (path[1] == ':') { int drive_letter = tolower(path[0]); st->st_rdev = st->st_dev = drive_letter - 'a'; } if (GetFileInformationByHandleEx(h, FileBasicInfo, &binfo, sizeof(binfo))) { FILETIME_LARGE_INTEGER_to_timespec(binfo.CreationTime, &st->st_ctim); st->st_ctime = st->st_ctim.tv_sec; FILETIME_LARGE_INTEGER_to_timespec(binfo.LastAccessTime, &st->st_atim); st->st_atime = st->st_atim.tv_sec; FILETIME_LARGE_INTEGER_to_timespec(binfo.LastWriteTime, &st->st_mtim); st->st_mtime = st->st_mtim.tv_sec; if (binfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { // This is a symlink, but msvcrt has no way to indicate that. // We'll treat it as a regular file until we have a better // representation :-/ st->st_mode = _S_IFREG; } else if (binfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { st->st_mode |= _S_IFDIR|S_IEXEC|S_IXGRP|S_IXOTH; } else { st->st_mode |= _S_IFREG; } if (binfo.FileAttributes & FILE_ATTRIBUTE_READONLY) { st->st_mode |= 0444; } else { st->st_mode |= 0666; } } if (GetFileInformationByHandleEx(h, FileStandardInfo, &sinfo, sizeof(sinfo))) { st->st_size = sinfo.EndOfFile.QuadPart; st->st_nlink = sinfo.NumberOfLinks; } CloseHandle(h); return 0; }
INT_PTR CALLBACK fssi_WindowHandler(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { const static DWORD dwStreamSize = 1024 * sizeof(FILE_STREAM_INFO); __declspec (align(64)) static PFILE_STREAM_INFO pfsi; static HANDLE hFile = nullptr; static HWND hListView = nullptr; static HWND hCreateButton = nullptr; switch ( uMsg ) { case WM_INITDIALOG: { hCreateButton = GetDlgItem(hDlg, IDC_CREATE_STREAM); hListView = GetDlgItem(hDlg, IDC_STREAM_LIST); pfsi = (PFILE_STREAM_INFO)LocalAlloc(LPTR, dwStreamSize); private_InitListView(hListView); return TRUE; } case WM_COMMAND: { switch ( LOWORD(wParam) ) { case IDM_VIEW_STREAM: { LPTSTR lpstrFileName; INT iSelected; iSelected = ListView_GetSelectionMark(hListView); if ( iSelected >= 0 ) { TCHAR szName[(MAX_PATH + 64) * sizeof(TCHAR)]; ListView_GetItemText(hListView, iSelected, 1, szName, sizeof(szName)); lpstrFileName = private_GetStreamName(hFile, szName); if ( lpstrFileName ) { MessageBox(hDlg, lpstrFileName, nullptr, 0); LocalFree(lpstrFileName); } } break; } case IDC_CREATE_STREAM: case IDM_CREATE_STREAM: { LPTSTR lpstrFileName; lpstrFileName = private_GetStreamName(hFile, TEXT("")); if ( lpstrFileName ) { LocalFree(lpstrFileName); } break; } } break; } case WM_NOTIFY: { LPNMHDR hdr = (LPNMHDR)lParam; switch (hdr->code) { case NM_RCLICK: { /** Or WM_MENUCOMMAND */ if ( hdr->idFrom == IDC_STREAM_LIST ) { HMENU hStreamMenu; BOOL bView = FALSE; UINT uFlags; POINT p; GetCursorPos(&p); uFlags = MF_BYPOSITION | MF_STRING | MF_POPUP; bView = ListView_GetSelectedCount(hListView) != 0; if ( !bView ) uFlags |= MF_DISABLED; if ( ListView_GetItemCount(hListView) == 0 ) break; hStreamMenu = CreatePopupMenu(); AppendMenu(hStreamMenu, uFlags, IDM_VIEW_STREAM, TEXT("Посмотреть")); AppendMenu(hStreamMenu, MF_BYPOSITION | MF_STRING, IDM_CREATE_STREAM, TEXT("Создать")); SetForegroundWindow(hListView); TrackPopupMenu(hStreamMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, p.x, p.y, 0, hListView, nullptr); DestroyMenu(hStreamMenu); } break; } } break; } case WM_SETFILE_HANDLE: { BOOL bClear; hFile = (HANDLE)lParam; if ( hFile && hFile != INVALID_HANDLE_VALUE ) { BOOL bResult; bClear = FALSE; bResult = GetFileInformationByHandleEx(hFile, FileStreamInfo, pfsi, dwStreamSize); if ( bResult ) { LVITEM lvItem; TCHAR szSubBuffer[1024]; INT nIndex; DWORD dwOffset; PFILE_STREAM_INFO pInfo; dwOffset = 0; nIndex = 0; pInfo = pfsi; ListView_DeleteAllItems(hListView); ZeroMemory( &lvItem, sizeof(lvItem) ); lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvItem.state = 0; lvItem.stateMask = 0; while (TRUE) { lvItem.iItem = nIndex; lvItem.iSubItem = 0; StringCchPrintf( szSubBuffer, sizeof(szSubBuffer), TEXT("%d"), nIndex); lvItem.pszText = szSubBuffer; lvItem.cchTextMax = lstrlen( szSubBuffer ); ListView_InsertItem( hListView, &lvItem ); /** Name */ //StringCchPrintf( szSubBuffer, sizeof(szSubBuffer), TEXT("%*.*S"), pInfo->StreamNameLength / 2, pInfo->StreamNameLength / 2, pInfo->StreamName ); StringCchPrintf( szSubBuffer, sizeof(szSubBuffer), TEXT("%s"), pInfo->StreamName ); ListView_SetItemText( hListView, nIndex, 1, szSubBuffer ); /** Size */ StringCchPrintf( szSubBuffer, sizeof(szSubBuffer), TEXT("%I64u"), pInfo->StreamSize); ListView_SetItemText( hListView, nIndex, 2, szSubBuffer ); /** Allocated size */ StringCchPrintf( szSubBuffer, sizeof(szSubBuffer), TEXT("%I64u"), pInfo->StreamAllocationSize); ListView_SetItemText( hListView, nIndex, 3, szSubBuffer ); ++nIndex; if ( !pInfo->NextEntryOffset ) break; pInfo = (PFILE_STREAM_INFO)( (LPBYTE)pInfo + pInfo->NextEntryOffset ); } } else { bClear = TRUE; } } else { bClear = TRUE; } if ( bClear ) { ListView_DeleteAllItems(hListView); } EnableWindow(hCreateButton, hFile != nullptr); break; } case WM_RESETFILE_HANDLE: { hFile = nullptr; break; } case WM_CLOSE: case WM_DESTROY: { LocalFree(pfsi); break; } } return FALSE; }