windows-nt/Source/XPSP1/NT/windows/winstate/cobra/utils/main/basefile.c

1514 lines
30 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
basefile.c
Abstract:
Contains simple wrappers for commonly used file i/o functions.
Author:
Marc R. Whitten (marcw) 02-Sep-1999
Revision History:
<alias> <date> <comments>
--*/
#include "pch.h"
//
// Includes
//
// None
#define DBG_BASEFILE "File Utils"
//
// Strings
//
// None
//
// Constants
//
// None
//
// Macros
//
// None
//
// Types
//
// None
//
// Globals
//
// None
//
// Macro expansion list
//
// None
//
// Private function prototypes
//
// None
//
// Macro expansion definition
//
// None
//
// Code
//
BOOL
WriteFileStringA (
IN HANDLE File,
IN PCSTR String
)
/*++
Routine Description:
Writes a DBCS string to the specified file.
Arguments:
File - Specifies the file handle that was opened with write access.
String - Specifies the nul-terminated string to write to the file.
Return Value:
TRUE if successful, FALSE if an error occurred. Call GetLastError
for error condition.
--*/
{
DWORD DontCare;
return WriteFile (File, String, ByteCountA (String), &DontCare, NULL);
}
BOOL
WriteFileStringW (
IN HANDLE File,
IN PCWSTR String
)
/*++
Routine Description:
Converts a UNICODE string to DBCS, then Writes it to the specified file.
Arguments:
File - Specifies the file handle that was opened with write access.
String - Specifies the UNICODE nul-terminated string to convert and
write to the file.
Return Value:
TRUE if successful, FALSE if an error occurred. Call GetLastError for
error condition.
--*/
{
DWORD DontCare;
PCSTR AnsiVersion;
BOOL b;
AnsiVersion = ConvertWtoA (String);
if (!AnsiVersion) {
return FALSE;
}
b = WriteFile (File, AnsiVersion, ByteCountA (AnsiVersion), &DontCare, NULL);
FreeConvertedStr (AnsiVersion);
return b;
}
BOOL
DoesFileExistExA(
IN PCSTR FileName,
OUT PWIN32_FIND_DATAA FindData OPTIONAL
)
/*++
Routine Description:
Determine if a file exists and is accessible.
Errormode is set (and then restored) so the user will not see
any pop-ups.
Arguments:
FileName - supplies full path of file to check for existance.
FindData - if specified, receives find data for the file.
Return Value:
TRUE if the file exists and is accessible.
FALSE if not. GetLastError() returns extended error info.
--*/
{
WIN32_FIND_DATAA ourFindData;
HANDLE FindHandle;
UINT OldMode;
DWORD Error;
if (!FindData) {
// Win95 GetFileAttributes does not return a failure if FileName is NULL
if (FileName == NULL) {
return FALSE;
} else {
return GetFileAttributesA (FileName) != 0xffffffff;
}
}
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
FindHandle = FindFirstFileA(FileName, &ourFindData);
if (FindHandle == INVALID_HANDLE_VALUE) {
Error = GetLastError();
} else {
FindClose(FindHandle);
*FindData = ourFindData;
Error = NO_ERROR;
}
SetErrorMode(OldMode);
SetLastError(Error);
return (Error == NO_ERROR);
}
BOOL
DoesFileExistExW (
IN PCWSTR FileName,
OUT PWIN32_FIND_DATAW FindData OPTIONAL
)
/*++
Routine Description:
Determine if a file exists and is accessible.
Errormode is set (and then restored) so the user will not see
any pop-ups.
Arguments:
FileName - supplies full path of file to check for existance.
FindData - if specified, receives find data for the file.
Return Value:
TRUE if the file exists and is accessible.
FALSE if not. GetLastError() returns extended error info.
--*/
{
WIN32_FIND_DATAW ourFindData;
HANDLE FindHandle;
UINT OldMode;
DWORD Error;
if (!FindData) {
// Win95 GetFileAttributes does not return a failure if FileName is NULL
if (FileName == NULL) {
return FALSE;
} else {
return GetFileAttributesW (FileName) != 0xffffffff;
}
}
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
FindHandle = FindFirstFileW(FileName,&ourFindData);
if (FindHandle == INVALID_HANDLE_VALUE) {
Error = GetLastError();
} else {
FindClose(FindHandle);
*FindData = ourFindData;
Error = NO_ERROR;
}
SetErrorMode(OldMode);
SetLastError(Error);
return (Error == NO_ERROR);
}
/*++
Routine Description:
PathIsDirectory determines if a path identifies an accessible directory.
Arguments:
PathSpec - Specifies the full path.
Return Value:
TRUE if the path identifies a directory.
FALSE if not. GetLastError() returns extended error info.
--*/
BOOL
BfPathIsDirectoryA (
IN PCSTR PathSpec
)
{
DWORD attribs;
MYASSERT (PathSpec);
if (!PathSpec) {
return FALSE;
}
attribs = GetFileAttributesA (PathSpec);
return attribs != (DWORD)-1 && (attribs & FILE_ATTRIBUTE_DIRECTORY);
}
BOOL
BfPathIsDirectoryW (
IN PCWSTR PathSpec
)
{
DWORD attribs;
MYASSERT (PathSpec);
if (!PathSpec) {
return FALSE;
}
attribs = GetFileAttributesW (PathSpec);
return attribs != (DWORD)-1 && (attribs & FILE_ATTRIBUTE_DIRECTORY);
}
PVOID
MapFileIntoMemoryExA (
IN PCSTR FileName,
OUT PHANDLE FileHandle,
OUT PHANDLE MapHandle,
IN BOOL WriteAccess
)
/*++
Routine Description:
MapFileIntoMemoryA and MapFileIntoMemoryW map a file into memory. It does that
by opening the file, creating a mapping object and mapping opened file into
created mapping object. It returnes the address where the file is mapped and
also sets FileHandle and MapHandle variables to be used in order to unmap the
file when work is done.
Arguments:
FileName - the name of the file to be mapped into memory
FileHandle - will end keeping the file handle if the file was opened successfully
MapHandle - will end keeping the mapping object handle if this object was created successfully
Return Value:
NULL if function fails, a valid memory address if successfull
Comments:
If the return value is NULL you should call UnmapFile to release all allocated resources
--*/
{
PVOID fileImage = NULL;
//verify function parameters
if ((FileHandle == NULL) || (MapHandle == NULL)) {
return NULL;
}
//first thing. Try to open the file, read-only
*FileHandle = CreateFileA (
FileName,
WriteAccess?GENERIC_READ|GENERIC_WRITE:GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (*FileHandle == INVALID_HANDLE_VALUE) {
*FileHandle = NULL;
return NULL;
}
//now try to create a mapping object, read-only
*MapHandle = CreateFileMappingA (*FileHandle, NULL, WriteAccess?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
if (*MapHandle == NULL) {
CloseHandle (*FileHandle);
*FileHandle = NULL;
return NULL;
}
//one more thing to do: map view of file
fileImage = MapViewOfFile (*MapHandle, WriteAccess?FILE_MAP_WRITE:FILE_MAP_READ, 0, 0, 0);
return fileImage;
}
PVOID
MapFileIntoMemoryExW (
IN PCWSTR FileName,
OUT PHANDLE FileHandle,
OUT PHANDLE MapHandle,
IN BOOL WriteAccess
)
/*++
Routine Description:
MapFileIntoMemoryA and MapFileIntoMemoryW map a file into memory. It does that
by opening the file, creating a mapping object and mapping opened file into
created mapping object. It returnes the address where the file is mapped and
also sets FileHandle and MapHandle variables to be used in order to unmap the
file when work is done.
Arguments:
FileName - the name of the file to be mapped into memory
FileHandle - will end keeping the file handle if the file was opened successfully
MapHandle - will end keeping the mapping object handle if this object was created successfully
Return Value:
NULL if function fails, a valid memory address if successfull
Comments:
If the return value is NULL you should call UnmapFile to release all allocated resources
--*/
{
PVOID fileImage = NULL;
//verify function parameters
if ((FileHandle == NULL) || (MapHandle == NULL)) {
return NULL;
}
//first thing. Try to open the file, read-only
*FileHandle = CreateFileW (
FileName,
WriteAccess?GENERIC_READ|GENERIC_WRITE:GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (*FileHandle == INVALID_HANDLE_VALUE) {
*FileHandle = NULL;
return NULL;
}
//now try to create a mapping object, read-only
*MapHandle = CreateFileMappingW (*FileHandle, NULL, WriteAccess?PAGE_READWRITE:PAGE_READONLY, 0, 0, NULL);
if (*MapHandle == NULL) {
CloseHandle (*FileHandle);
*FileHandle = NULL;
return NULL;
}
//one more thing to do: map view of file
fileImage = MapViewOfFile (*MapHandle, WriteAccess?FILE_MAP_WRITE:FILE_MAP_READ, 0, 0, 0);
return fileImage;
}
BOOL
UnmapFile (
IN PCVOID FileImage,
IN HANDLE MapHandle,
IN HANDLE FileHandle
)
/*++
Routine Description:
UnmapFile is used to release all resources allocated by MapFileIntoMemory.
Arguments:
FileImage - image of the mapped file as returned by MapFileIntoMemory
MapHandle - handle of the mapping object as returned by MapFileIntoMemory
FileHandle - handle of the file as returned by MapFileIntoMemory
Return Value:
TRUE if successfull, FALSE if not
--*/
{
BOOL result = TRUE;
//if FileImage is a valid pointer then try to unmap file
if (FileImage != NULL) {
if (UnmapViewOfFile (FileImage) == 0) {
result = FALSE;
}
}
//if mapping object is valid then try to delete it
if (MapHandle != NULL) {
if (CloseHandle (MapHandle) == 0) {
result = FALSE;
}
}
//if file handle is valid then try to close the file
if (FileHandle != INVALID_HANDLE_VALUE) {
if (CloseHandle (FileHandle) == 0) {
result = FALSE;
}
}
return result;
}
BOOL
BfGetTempFileNameExA (
OUT PSTR Buffer,
IN UINT BufferTchars,
IN PCSTR Prefix
)
{
CHAR tempPath[MAX_MBCHAR_PATH];
CHAR tempFile[MAX_MBCHAR_PATH];
UINT tchars;
PSTR p;
if (!GetTempPathA (ARRAYSIZE(tempPath), tempPath)) {
return FALSE;
}
p = _mbsrchr (tempPath, '\\');
if (p && !p[1]) {
*p = 0;
}
if (!DoesFileExistA (tempPath)) {
BfCreateDirectoryA (tempPath);
}
if (BufferTchars >= MAX_PATH) {
if (!GetTempFileNameA (tempPath, Prefix, 0, Buffer)) {
return FALSE;
}
} else {
if (!GetTempFileNameA (tempPath, Prefix, 0, tempFile)) {
DWORD err = GetLastError ();
return FALSE;
}
tchars = TcharCountA (tempFile) + 1;
if (tchars > BufferTchars) {
DEBUGMSG ((DBG_ERROR, "Can't get temp file name -- buffer too small"));
return FALSE;
}
CopyMemory (Buffer, tempFile, tchars * sizeof (CHAR));
}
return TRUE;
}
BOOL
BfGetTempFileNameExW (
OUT PWSTR Buffer,
IN UINT BufferTchars,
IN PCWSTR Prefix
)
{
WCHAR tempPath[MAX_WCHAR_PATH];
WCHAR tempFile[MAX_WCHAR_PATH];
UINT tchars;
PWSTR p;
if (!GetTempPathW (ARRAYSIZE(tempPath), tempPath)) {
return FALSE;
}
p = wcsrchr (tempPath, '\\');
if (p && !p[1]) {
*p = 0;
}
if (BufferTchars >= MAX_PATH) {
if (!GetTempFileNameW (tempPath, Prefix, 0, Buffer)) {
return FALSE;
}
} else {
if (!GetTempFileNameW (tempPath, Prefix, 0, tempFile)) {
return FALSE;
}
tchars = TcharCountW (tempFile);
if (tchars > BufferTchars) {
DEBUGMSG ((DBG_ERROR, "Can't get temp file name -- buffer too small"));
return FALSE;
}
CopyMemory (Buffer, tempFile, tchars * sizeof (WCHAR));
}
return TRUE;
}
BOOL
BfGetTempDirectoryExA (
OUT PSTR Buffer,
IN UINT BufferTchars,
IN PCSTR Prefix
)
{
BOOL result = FALSE;
result = BfGetTempFileNameExA (Buffer, BufferTchars, Prefix);
if (result) {
if (!DeleteFileA (Buffer)) {
return FALSE;
}
if (!CreateDirectoryA (Buffer, NULL)) {
return FALSE;
}
}
return result;
}
BOOL
BfGetTempDirectoryExW (
OUT PWSTR Buffer,
IN UINT BufferTchars,
IN PCWSTR Prefix
)
{
BOOL result = FALSE;
result = BfGetTempFileNameExW (Buffer, BufferTchars, Prefix);
if (result) {
if (!DeleteFileW (Buffer)) {
return FALSE;
}
if (!CreateDirectoryW (Buffer, NULL)) {
return FALSE;
}
}
return result;
}
HANDLE
BfGetTempFile (
VOID
)
{
CHAR tempFile[MAX_MBCHAR_PATH];
HANDLE file;
if (!BfGetTempFileNameA (tempFile, ARRAYSIZE(tempFile))) {
return NULL;
}
file = CreateFileA (
tempFile,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE,
NULL
);
if (file == INVALID_HANDLE_VALUE) {
file = NULL;
}
return file;
}
BOOL
BfSetFilePointer (
IN HANDLE File,
IN LONGLONG Offset
)
{
LARGE_INTEGER li;
li.QuadPart = Offset;
li.LowPart = SetFilePointer (File, li.LowPart, &li.HighPart, FILE_BEGIN);
if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
li.QuadPart = -1;
}
return li.QuadPart != -1;
}
HANDLE
BfOpenReadFileA (
IN PCSTR FileName
)
{
HANDLE handle;
handle = CreateFileA (
FileName,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfOpenReadFileW (
IN PCWSTR FileName
)
{
HANDLE handle;
handle = CreateFileW (
FileName,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfOpenFileA (
IN PCSTR FileName
)
{
HANDLE handle;
handle = CreateFileA (
FileName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfOpenFileW (
IN PCWSTR FileName
)
{
HANDLE handle;
handle = CreateFileW (
FileName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfCreateFileA (
IN PCSTR FileName
)
{
HANDLE handle;
handle = CreateFileA (
FileName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfCreateFileW (
IN PCWSTR FileName
)
{
HANDLE handle;
handle = CreateFileW (
FileName,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfCreateSharedFileA (
IN PCSTR FileName
)
{
HANDLE handle;
handle = CreateFileA (
FileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
HANDLE
BfCreateSharedFileW (
IN PCWSTR FileName
)
{
HANDLE handle;
handle = CreateFileW (
FileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (handle == INVALID_HANDLE_VALUE) {
handle = NULL;
}
return handle;
}
BOOL
BfSetSizeOfFile (
HANDLE File,
LONGLONG Size
)
{
if (!BfSetFilePointer (File, Size)) {
return FALSE;
}
return SetEndOfFile (File);
}
BOOL
BfGoToEndOfFile (
IN HANDLE File,
OUT PLONGLONG FileSize OPTIONAL
)
{
LARGE_INTEGER li;
li.HighPart = 0;
li.LowPart = SetFilePointer (File, 0, &li.HighPart, FILE_END);
if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
li.QuadPart = -1;
} else if (FileSize) {
*FileSize = li.QuadPart;
}
return li.QuadPart != -1;
}
BOOL
BfGetFilePointer (
IN HANDLE File,
OUT PLONGLONG FilePointer OPTIONAL
)
{
LARGE_INTEGER li;
li.HighPart = 0;
li.LowPart = SetFilePointer (File, 0, &li.HighPart, FILE_CURRENT);
if (li.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
li.QuadPart = -1;
} else if (FilePointer) {
*FilePointer = li.QuadPart;
}
return li.QuadPart != -1;
}
BOOL
BfReadFile (
IN HANDLE File,
OUT PBYTE Buffer,
IN UINT BytesToRead
)
{
DWORD bytesRead;
if (!ReadFile (File, Buffer, BytesToRead, &bytesRead, NULL)) {
return FALSE;
}
return bytesRead == BytesToRead;
}
BOOL
BfWriteFile (
IN HANDLE File,
OUT PCBYTE Buffer,
IN UINT BytesToWrite
)
{
DWORD bytesWritten;
if (!WriteFile (File, Buffer, BytesToWrite, &bytesWritten, NULL)) {
return FALSE;
}
return bytesWritten == BytesToWrite;
}
BOOL
BfCreateDirectoryExA (
IN PCSTR FullPath,
IN BOOL CreateLastSegment
)
{
PSTR pathCopy;
PSTR p;
BOOL b = TRUE;
pathCopy = DuplicatePathStringA (FullPath, 0);
//
// Advance past first directory
//
if (pathCopy[1] == ':' && pathCopy[2] == '\\') {
//
// <drive>:\ case
//
p = _mbschr (&pathCopy[3], '\\');
} else if (pathCopy[0] == '\\' && pathCopy[1] == '\\') {
//
// UNC case
//
p = _mbschr (pathCopy + 2, '\\');
if (p) {
p = _mbschr (p + 1, '\\');
if (p) {
p = _mbschr (p + 1, '\\');
}
}
} else {
//
// Relative dir case
//
p = _mbschr (pathCopy, '\\');
}
//
// Make all directories along the path
//
while (p) {
*p = 0;
b = CreateDirectoryA (pathCopy, NULL);
if (!b && GetLastError() == ERROR_ALREADY_EXISTS) {
b = TRUE;
}
if (!b) {
LOG ((LOG_ERROR, "Can't create %s", pathCopy));
break;
}
*p = '\\';
p = _mbschr (p + 1, '\\');
}
//
// At last, make the FullPath directory
//
if (b && CreateLastSegment) {
b = CreateDirectoryA (pathCopy, NULL);
if (!b && GetLastError() == ERROR_ALREADY_EXISTS) {
b = TRUE;
}
}
FreePathStringA (pathCopy);
return b;
}
BOOL
BfCreateDirectoryExW (
IN PCWSTR FullPath,
IN BOOL CreateLastSegment
)
{
PWSTR pathCopy;
PWSTR p;
BOOL b = TRUE;
pathCopy = DuplicatePathStringW (FullPath, 0);
//
// Advance past first directory
//
if (pathCopy[1] == L':' && pathCopy[2] == L'\\') {
//
// <drive>:\ case
//
p = wcschr (&pathCopy[3], L'\\');
} else if (pathCopy[0] == L'\\' && pathCopy[1] == L'\\') {
//
// UNC case
//
p = wcschr (pathCopy + 2, L'\\');
if (p) {
p = wcschr (p + 1, L'\\');
if (p) {
p = wcschr (p + 1, L'\\');
}
}
} else {
//
// Relative dir case
//
p = wcschr (pathCopy, L'\\');
}
//
// Make all directories along the path
//
while (p) {
*p = 0;
b = CreateDirectoryW (pathCopy, NULL);
if (!b && GetLastError() == ERROR_ALREADY_EXISTS) {
b = TRUE;
}
if (!b) {
break;
}
*p = L'\\';
p = wcschr (p + 1, L'\\');
}
//
// At last, make the FullPath directory
//
if (b && CreateLastSegment) {
b = CreateDirectoryW (pathCopy, NULL);
if (!b && GetLastError() == ERROR_ALREADY_EXISTS) {
b = TRUE;
}
}
FreePathStringW (pathCopy);
return b;
}
LONGLONG
BfGetFileSizeA (
IN PCSTR FileName
)
{
WIN32_FIND_DATAA fd;
LONGLONG l;
if (!DoesFileExistExA (FileName, &fd)) {
return 0;
}
l = ((LONGLONG) fd.nFileSizeHigh << 32) | fd.nFileSizeLow;
return l;
}
LONGLONG
BfGetFileSizeW (
IN PCWSTR FileName
)
{
WIN32_FIND_DATAW fd;
LONGLONG l;
if (!DoesFileExistExW (FileName, &fd)) {
return 0;
}
l = ((LONGLONG) fd.nFileSizeHigh << 32) | fd.nFileSizeLow;
return l;
}
PSTR
pGetFirstSegA (
IN PCSTR SrcFileName
)
{
if (SrcFileName [0] == '\\') {
SrcFileName ++;
if (SrcFileName [0] == '\\') {
SrcFileName ++;
}
return (_mbschr (SrcFileName, '\\'));
} else {
return (_mbschr (SrcFileName, '\\'));
}
}
BOOL
pGetLongFileNameWorkerA (
IN PCSTR SrcFileName,
IN PGROWBUFFER GrowBuf
)
{
PSTR beginSegPtr;
PSTR endSegPtr;
WIN32_FIND_DATAA findData;
CHAR savedChar;
beginSegPtr = pGetFirstSegA (SrcFileName);
if (!beginSegPtr) {
GbAppendStringA (GrowBuf, SrcFileName);
return TRUE;
}
beginSegPtr = _mbsinc (beginSegPtr);
GbAppendStringABA (GrowBuf, SrcFileName, beginSegPtr);
while (beginSegPtr) {
endSegPtr = _mbschr (beginSegPtr, '\\');
if (!endSegPtr) {
endSegPtr = GetEndOfStringA (beginSegPtr);
MYASSERT (endSegPtr);
}
savedChar = *endSegPtr;
*endSegPtr = 0;
if (DoesFileExistExA (SrcFileName, &findData)) {
if (StringIMatchA (findData.cFileName, ".")) {
GbAppendStringA (GrowBuf, beginSegPtr);
} else {
GbAppendStringA (GrowBuf, findData.cFileName);
}
} else {
GbAppendStringABA (GrowBuf, beginSegPtr, endSegPtr);
}
*endSegPtr = savedChar;
if (savedChar) {
beginSegPtr = _mbsinc (endSegPtr);
GbAppendStringABA (GrowBuf, endSegPtr, beginSegPtr);
} else {
beginSegPtr = NULL;
}
}
return TRUE;
}
PCSTR
BfGetLongFileNameA (
IN PCSTR SrcFileName
)
{
GROWBUFFER growBuf = INIT_GROWBUFFER;
PSTR srcFileName;
PCSTR result = NULL;
srcFileName = (PSTR)SanitizePathA (SrcFileName);
if (pGetLongFileNameWorkerA (srcFileName, &growBuf)) {
result = DuplicatePathStringA (growBuf.Buf, 0);
GbFree (&growBuf);
}
FreePathStringA (srcFileName);
return result;
}
BOOL
BfGetLongFileNameExA (
IN PCSTR SrcFileName,
IN PGROWBUFFER GrowBuff
)
{
PSTR srcFileName;
BOOL result;
srcFileName = (PSTR)SanitizePathA (SrcFileName);
result = pGetLongFileNameWorkerA (srcFileName, GrowBuff);
FreePathStringA (srcFileName);
return result;
}
PWSTR
pGetFirstSegW (
IN PCWSTR SrcFileName
)
{
if (SrcFileName [0] == L'\\') {
SrcFileName ++;
if (SrcFileName [0] == L'\\') {
SrcFileName ++;
}
return (wcschr (SrcFileName, L'\\'));
} else {
return (wcschr (SrcFileName, L'\\'));
}
}
BOOL
pGetLongFileNameWorkerW (
IN PCWSTR SrcFileName,
IN PGROWBUFFER GrowBuf
)
{
PWSTR beginSegPtr;
PWSTR endSegPtr;
WIN32_FIND_DATAW findData;
WCHAR savedChar;
beginSegPtr = pGetFirstSegW (SrcFileName);
if (!beginSegPtr) {
GbAppendStringW (GrowBuf, SrcFileName);
return TRUE;
}
beginSegPtr ++;
GbAppendStringABW (GrowBuf, SrcFileName, beginSegPtr);
while (beginSegPtr) {
endSegPtr = wcschr (beginSegPtr, L'\\');
if (!endSegPtr) {
endSegPtr = GetEndOfStringW (beginSegPtr);
MYASSERT (endSegPtr);
}
savedChar = *endSegPtr;
*endSegPtr = 0;
if (DoesFileExistExW (SrcFileName, &findData)) {
GbAppendStringW (GrowBuf, findData.cFileName);
} else {
GbAppendStringABW (GrowBuf, beginSegPtr, endSegPtr);
}
*endSegPtr = savedChar;
if (savedChar) {
beginSegPtr = endSegPtr + 1;
GbAppendStringABW (GrowBuf, endSegPtr, beginSegPtr);
} else {
beginSegPtr = NULL;
}
}
return TRUE;
}
PCWSTR
BfGetLongFileNameW (
IN PCWSTR SrcFileName
)
{
GROWBUFFER growBuf = INIT_GROWBUFFER;
PWSTR srcFileName;
PCWSTR result = NULL;
srcFileName = (PWSTR)SanitizePathW (SrcFileName);
if (pGetLongFileNameWorkerW (srcFileName, &growBuf)) {
result = DuplicatePathStringW ((PCWSTR)growBuf.Buf, 0);
GbFree (&growBuf);
}
FreePathStringW (srcFileName);
return result;
}
BOOL
BfGetLongFileNameExW (
IN PCWSTR SrcFileName,
IN PGROWBUFFER GrowBuff
)
{
PWSTR srcFileName;
BOOL result;
srcFileName = (PWSTR)SanitizePathW (SrcFileName);
result = pGetLongFileNameWorkerW (srcFileName, GrowBuff);
FreePathStringW (srcFileName);
return result;
}
BOOL
BfCopyAndFlushFileA (
IN PCSTR SrcFileName,
IN PCSTR DestFileName,
IN BOOL FailIfExists
)
{
BYTE buffer[4096];
HANDLE srcHandle;
HANDLE destHandle;
DWORD bytesRead = 4096;
DWORD bytesWritten;
BOOL error = FALSE;
BOOL result = FALSE;
srcHandle = BfOpenReadFileA (SrcFileName);
if (srcHandle) {
if (FailIfExists && DoesFileExistA (DestFileName)) {
SetLastError (ERROR_ALREADY_EXISTS);
} else {
destHandle = BfCreateFileA (DestFileName);
if (destHandle) {
while (bytesRead == 4096) {
if (!ReadFile (srcHandle, buffer, 4096, &bytesRead, NULL)) {
error = TRUE;
break;
}
if (bytesRead == 0) {
break;
}
if (!WriteFile (destHandle, buffer, bytesRead, &bytesWritten, NULL)) {
error = TRUE;
break;
}
if (bytesRead != bytesWritten) {
error = TRUE;
break;
}
}
if (!error) {
result = TRUE;
}
if (result) {
FlushFileBuffers (destHandle);
}
CloseHandle (destHandle);
}
}
CloseHandle (srcHandle);
}
return result;
}
BOOL
BfCopyAndFlushFileW (
IN PCWSTR SrcFileName,
IN PCWSTR DestFileName,
IN BOOL FailIfExists
)
{
BYTE buffer[4096];
HANDLE srcHandle;
HANDLE destHandle;
DWORD bytesRead = 4096;
DWORD bytesWritten;
BOOL error = FALSE;
BOOL result = FALSE;
srcHandle = BfOpenReadFileW (SrcFileName);
if (srcHandle) {
if (FailIfExists && DoesFileExistW (DestFileName)) {
SetLastError (ERROR_ALREADY_EXISTS);
} else {
destHandle = BfCreateFileW (DestFileName);
if (destHandle) {
while (bytesRead == 4096) {
if (!ReadFile (srcHandle, buffer, 4096, &bytesRead, NULL)) {
error = TRUE;
break;
}
if (bytesRead == 0) {
break;
}
if (!WriteFile (destHandle, buffer, bytesRead, &bytesWritten, NULL)) {
error = TRUE;
break;
}
if (bytesRead != bytesWritten) {
error = TRUE;
break;
}
}
if (!error) {
result = TRUE;
}
if (result) {
FlushFileBuffers (destHandle);
}
CloseHandle (destHandle);
}
}
CloseHandle (srcHandle);
}
return result;
}