Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1384 lines
32 KiB

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
Utils.C
Abstract:
a collection of utility functions used by other routines.
Author:
Bob Watson (a-robw)
Revision History:
24 Aug 1994 Written
--*/
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include "c2inc.h"
#include "c2utils.h"
#include "strings.h"
#define NUM_BUFS 4
//
// local "helper" functions
//
static
BOOL
MediaPresent (
IN LPCTSTR szPath,
IN BOOL bPresentAndValid
)
/*++
Routine Description:
determines if the specified path is present and available
Arguments:
IN LPCTSTR szPath
path to examine (Must be a DOS path)
Return Value:
TRUE: path is available
FALSE: unable to find/open path
--*/
{
BOOL bMediaPresent = FALSE;
TCHAR szDev[8];
DWORD dwBytes = 0;
DWORD dwAttrib;
DWORD dwLastError = ERROR_SUCCESS;
UINT nErrorMode;
if (!IsUncPath(szPath)) {
// build device name string
szDev[0] = szPath[0];
szDev[1] = cColon;
szDev[2] = cBackslash;
szDev[3] = 0;
// disable windows error message popup
nErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
dwAttrib = QuietGetFileAttributes (szDev);
if ((dwAttrib != 0xFFFFFFFF) && ((dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
// if the root dir is a dir, then it must be present and formatted
bMediaPresent = TRUE;
} else {
// otherwise see if it's present and not formatted or not present
dwLastError = GetMyLastError();
if (dwLastError == ERROR_NOT_READY) {
// then no disk in drive
bMediaPresent = FALSE;
} else if ((dwLastError == ERROR_FILE_NOT_FOUND) ||
(dwLastError == ERROR_UNRECOGNIZED_MEDIA)) {
// then and UNFORMATTED disk is in drive
if (bPresentAndValid) {
// this isn't good enough if it's supposed to be formatted
bMediaPresent = FALSE;
} else {
// we're just looking for a disk so this is OK
bMediaPresent = TRUE;
}
}
}
SetErrorMode (nErrorMode); // restore old error mode
} else {
// assume UNC path devices are present
bMediaPresent = TRUE;
}
return bMediaPresent;
}
//
// Global functions
//
DWORD
QuietGetFileAttributes (
IN LPCTSTR lpszFileName
)
/*++
Routine Description:
Reads the attributes of the path in lpzsFileName without triggering
any Windows error dialog if there's an OS error (e.g. drive not
ready)
Arguments:
IN LPCTSTR lpszFileName
path to retrieve attributes from
Return Value:
file attributes DWORD returned from GetFileAttributes or
0xFFFFFFFF if unable to open path.
--*/
{
DWORD dwReturn;
UINT nErrorMode;
unsigned uAttrib; // used in WIN 16 builds only
// disable windows error message popup
nErrorMode = SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#ifdef WIN32
dwReturn = GetFileAttributes (lpszFileName);
uAttrib = 0; // to prevent unused var error in WIN32 build
#else // WIN16
if (_dos_getfileattr (lpszFileName, &uAttrib) == 0) {
dwReturn = uAttrib;
} else {
dwReturn = 0xFFFFFFFF;
SetLastError (ERROR_FILE_NOT_FOUND);
}
#endif
SetErrorMode (nErrorMode); // restore old error mode
return dwReturn;
}
BOOL
EnableSecurityPriv (
)
{
HANDLE hToken;
LUID SeSecurityNameValue;
TOKEN_PRIVILEGES tkp;
/* Retrieve a handle of the access token. */
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken)) {
return FALSE;
}
/*
* Enable the SE_SECURITY_NAME privilege
*/
if (!LookupPrivilegeValue((LPCTSTR) NULL,
SE_SECURITY_NAME,
&SeSecurityNameValue)) {
return FALSE;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = SeSecurityNameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,
FALSE,
&tkp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL);
if (GetLastError() != ERROR_SUCCESS) {
return FALSE;
} else {
return TRUE;
}
}
BOOL
EnableAllPriv (
)
/*++
Routine Description:
This routine enables all privileges in the token.
Arguments:
None.
Return Value:
None.
--*/
{
HANDLE Token;
ULONG ReturnLength, Index;
PTOKEN_PRIVILEGES NewState;
BOOL Result;
Token = NULL;
NewState = NULL;
Result = OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&Token
);
if (Result) {
ReturnLength = 4096;
NewState = malloc( ReturnLength );
Result = (BOOL)(NewState != NULL);
if (Result) {
Result = GetTokenInformation( Token, // TokenHandle
TokenPrivileges, // TokenInformationClass
NewState, // TokenInformation
ReturnLength, // TokenInformationLength
&ReturnLength // ReturnLength
);
if (Result) {
//
// Set the state settings so that all privileges are enabled...
//
if (NewState->PrivilegeCount > 0) {
for (Index = 0; Index < NewState->PrivilegeCount; Index++ ) {
NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED;
}
}
Result = AdjustTokenPrivileges( Token, // TokenHandle
FALSE, // DisableAllPrivileges
NewState, // NewState (OPTIONAL)
ReturnLength, // BufferLength
NULL, // PreviousState (OPTIONAL)
&ReturnLength // ReturnLength
);
}
}
}
if (NewState != NULL) {
free( NewState );
}
if (Token != NULL) {
CloseHandle( Token );
}
return( Result );
}
#ifdef _UNICODE
FARPROC
GetProcAddressW (
IN HMODULE hModule,
IN LPCWSTR lpwszProc
)
{
LPSTR szProc;
LONG lProcLen;
LONG lAnsiLen;
FARPROC lpReturn;
lProcLen = lstrlen(lpwszProc);
szProc = GLOBAL_ALLOC (lProcLen + 1);
if (szProc != NULL) {
lAnsiLen = wcstombs (szProc, lpwszProc, lProcLen);
if (lAnsiLen == lProcLen) {
lpReturn = GetProcAddress (
hModule,
szProc);
} else {
lpReturn = NULL;
}
// free allocated string buffer
GLOBAL_FREE_IF_ALLOC (szProc);
} else {
lpReturn = NULL;
}
return lpReturn;
}
#endif
#ifdef _UNICODE
HFILE
OpenFileW(
LPCTSTR lpwszFile,
LPWOFSTRUCT lpWOpenBuff,
UINT fuMode
)
{
LPSTR szFileName;
OFSTRUCT ofStruct;
HFILE hReturn;
LONG lFileNameLen;
LONG lAnsiNameLen;
// check arguments
if ((lpwszFile == NULL) || (lpWOpenBuff == NULL)) {
SetLastError (ERROR_INVALID_PARAMETER);
hReturn = HFILE_ERROR;
} else {
lFileNameLen = lstrlen(lpwszFile);
szFileName = GLOBAL_ALLOC (lFileNameLen + 1);
if (szFileName != NULL) {
lAnsiNameLen = wcstombs (szFileName, lpwszFile, lFileNameLen);
if (lAnsiNameLen == lFileNameLen) {
hReturn = OpenFile (
szFileName,
&ofStruct,
fuMode);
if (hReturn != HFILE_ERROR){
lpWOpenBuff->cBytes = ofStruct.cBytes;
lpWOpenBuff->fFixedDisk = ofStruct.fFixedDisk;
lpWOpenBuff->nErrCode = ofStruct.nErrCode;
lpWOpenBuff->Reserved1 = ofStruct.Reserved1;
lpWOpenBuff->Reserved2 = ofStruct.Reserved2;
lAnsiNameLen = strlen (ofStruct.szPathName);
mbstowcs (lpWOpenBuff->szPathName,
ofStruct.szPathName, lAnsiNameLen);
}
}
GLOBAL_FREE_IF_ALLOC (szFileName);
} else {
SetLastError (ERROR_OUTOFMEMORY);
hReturn = HFILE_ERROR;
}
}
return hReturn;
}
#endif
BOOL
TrimSpaces (
IN OUT LPTSTR szString
)
/*++
Routine Description:
Trims leading and trailing spaces from szString argument, modifying
the buffer passed in
Arguments:
IN OUT LPTSTR szString
buffer to process
Return Value:
TRUE if string was modified
FALSE if not
--*/
{
LPTSTR szSource;
LPTSTR szDest;
LPTSTR szLast;
BOOL bChars;
szLast = szSource = szDest = szString;
bChars = FALSE;
while (*szSource != 0) {
// skip leading non-space chars
if (*szSource > cSpace) {
szLast = szDest;
bChars = TRUE;
}
if (bChars) {
// remember last non-space character
// copy source to destination & increment both
*szDest++ = *szSource++;
} else {
szSource++;
}
}
if (bChars) {
*++szLast = 0; // terminate after last non-space char
} else {
// string was all spaces so return an empty (0-len) string
*szString = 0;
}
return (szLast != szSource);
}
BOOL
IsUncPath (
IN LPCTSTR szPath
)
/*++
Routine Description:
examines path as a string looking for "tell-tale" double
backslash indicating the machine name syntax of a UNC path
Arguments:
IN LPCTSTR szPath
path to examine
Return Value:
TRUE if \\ found at start of string
FALSE if not
--*/
{
LPTSTR szPtChar;
szPtChar = (LPTSTR)szPath;
if (*szPtChar == cBackslash) {
if (*++szPtChar == cBackslash) {
return TRUE;
}
}
return FALSE;
}
LPTSTR
GetFileNameFromPath (
IN LPCTSTR szPath
)
{
LPTSTR szLastBs;
LPTSTR szThisChar;
szLastBs = (LPTSTR)szPath;
for (szThisChar = (LPTSTR)szPath; *szThisChar != 0; szThisChar++) {
if (*szThisChar == cBackslash) {
szLastBs = szThisChar;
}
}
if (*szLastBs == cBackslash) {
szLastBs++;
}
return szLastBs;
}
BOOL
CenterWindow (
HWND hwndChild,
HWND hwndParent
)
/*++
Routine Description:
Centers the child window in the Parent window
Arguments:
HWND hwndChild,
handle of child window to center
HWND hwndParent
handle of parent window to center child window in
ReturnValue:
Return value of SetWindowPos
--*/
{
RECT rChild, rParent;
LONG wChild, hChild, wParent, hParent;
LONG wScreen, hScreen, xNew, yNew;
HDC hdc;
// Get the Height and Width of the child window
GetWindowRect (hwndChild, &rChild);
wChild = rChild.right - rChild.left;
hChild = rChild.bottom - rChild.top;
// Get the Height and Width of the parent window
GetWindowRect (hwndParent, &rParent);
wParent = rParent.right - rParent.left;
hParent = rParent.bottom - rParent.top;
// Get the display limits
hdc = GetDC (hwndChild);
wScreen = GetDeviceCaps (hdc, HORZRES);
hScreen = GetDeviceCaps (hdc, VERTRES);
ReleaseDC (hwndChild, hdc);
// Calculate new X position, then adjust for screen
xNew = rParent.left + ((wParent - wChild) /2);
if (xNew < 0) {
xNew = 0;
} else if ((xNew+wChild) > wScreen) {
xNew = wScreen - wChild;
}
// Calculate new Y position, then adjust for screen
yNew = rParent.top + ((hParent - hChild) /2);
if (yNew < 0) {
yNew = 0;
} else if ((yNew+hChild) > hScreen) {
yNew = hScreen - hChild;
}
// Set it, and return
return SetWindowPos (hwndChild, NULL,
(int)xNew, (int)yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
UINT
GetDriveTypeFromDosPath (
IN LPCTSTR szDosPath
)
/*++
Routine Description:
Strips the filename and path from the path in the argument and returns
the drive type as returned by the GetDriveType Win32 API fn.
Arguments:
IN LPCTSTR szDosPath
dos path in the format: <Drive>:\path... This format is NOT checked
by the function!
Return Value:
DRIVE TYPE value returned by the GetDriveType API.
--*/
{
#ifdef WIN32
TCHAR szRootDir[4];
szRootDir[0] = szDosPath[0];
szRootDir[1] = cColon;
szRootDir[2] = cBackslash;
szRootDir[3] = 0;
#else // win16 version isn't as robust
int szRootDir; // not really an SZ, but it keeps the call compatible
TCHAR szLocalPath[4];
szLocalPath[0] = szDosPath[0];
szLocalPath[1] = 0;
_strupr(szLocalPath);
szRootDir = szLocalPath[0] - cA;
#endif
return (GetDriveType(szRootDir));
}
LPCTSTR
GetItemFromIniEntry (
IN LPCTSTR szEntry,
IN DWORD dwItem
)
/*++
Routine Description:
returns nth item from comma separated list returned from
inf file. leaves (double)quoted strings intact.
Arguments:
IN LPCTSTR szEntry
entry string returned from INF file
IN DWORD dwItem
1-based index indicating which item to return. (i.e. 1= first item
in list, 2= second, etc.)
Return Value:
pointer to buffer containing desired entry in string. Note, this
routine may only be called 4 times before the string
buffer is re-used. (i.e. don't use this function more than
4 times in single function call!!)
--*/
{
static TCHAR szReturnBuffer[4][MAX_PATH];
static LONG dwBuff;
LPTSTR szSource, szDest;
DWORD dwThisItem;
dwBuff = ++dwBuff % 4; // wrap buffer index
szSource = (LPTSTR)szEntry;
szDest = &szReturnBuffer[dwBuff][0];
// clear previous contents
memset (szDest, 0, (MAX_PATH * sizeof(TCHAR)));
// go past ini key
while ((*szSource != cEqual) && (*szSource != 0)) szSource++;
if (*szSource == 0){
// no equals found so start at beginning
// presumably this is just the "value"
szSource = (LPTSTR)szEntry;
} else {
szSource++;
}
dwThisItem = 1;
while (dwThisItem < dwItem) {
if (*szSource != 0) {
while ((*szSource != cComma) && (*szSource != 0)) {
if (*szSource == cDoubleQuote) {
// if this is a quote, then go to the close quote
szSource++;
while ((*szSource != cDoubleQuote) && (*szSource != 0)) szSource++;
}
if (*szSource != 0) szSource++;
}
}
dwThisItem++;
if (*szSource != 0) szSource++;
}
// copy this entry to the return buffer
if (*szSource != 0) {
while ((*szSource != cComma) && (*szSource != 0)) {
if (*szSource == cDoubleQuote) {
// if this is a quote, then go to the close quote
// don't copy quotes!
szSource++;
while ((*szSource != cDoubleQuote) && (*szSource != 0)) {
*szDest++ = *szSource++;
}
if (*szSource != 0) szSource++;
} else {
*szDest++ = *szSource++;
}
}
*szDest = 0;
}
// remove any leading and/or trailing spaces
TrimSpaces (&szReturnBuffer[dwBuff][0]);
return &szReturnBuffer[dwBuff][0];
}
LPCTSTR
GetStringResource (
IN HANDLE hInstance,
IN UINT nId
)
/*++
Routine Description:
look up string resource and return string
Arguments:
IN UINT nId
Resource ID of string to look up
Return Value:
pointer to string referenced by ID in arg list
--*/
{
static TCHAR szBufArray[NUM_BUFS][SMALL_BUFFER_SIZE];
static DWORD dwIndex;
LPTSTR szBuffer;
DWORD dwLength;
HANDLE hMod;
if (hInstance != NULL) {
hMod = hInstance;
} else {
hMod = GetModuleHandle(NULL);
}
dwIndex++;
dwIndex %= NUM_BUFS;
szBuffer = &szBufArray[dwIndex][0];
// clear previous contents
memset (szBuffer, 0, (SMALL_BUFFER_SIZE * sizeof(TCHAR)));
dwLength = LoadString (
hMod,
nId,
szBuffer,
SMALL_BUFFER_SIZE);
return (LPCTSTR)szBuffer;
}
LPCTSTR
GetQuotedStringResource (
IN HANDLE hInstance,
IN UINT nId
)
/*++
Routine Description:
look up string resource and return string inside double quotes
Arguments:
IN HANDLE hInstance
handle to application instance
IN UINT nId
Resource ID of string to look up
Return Value:
pointer to string referenced by ID in arg list
--*/
{
static TCHAR szBufArray[NUM_BUFS][SMALL_BUFFER_SIZE];
static DWORD dwIndex;
LPTSTR szBuffer;
DWORD dwLength;
HANDLE hMod;
if (hInstance != NULL) {
hMod = hInstance;
} else {
hMod = GetModuleHandle(NULL);
}
dwIndex++;
dwIndex %= NUM_BUFS;
szBuffer = &szBufArray[dwIndex][0];
// clear previous contents
memset (szBuffer, 0, (SMALL_BUFFER_SIZE * sizeof(TCHAR)));
szBuffer[0] = cSpace;
szBuffer[1] = cSpace;
szBuffer[2] = cDoubleQuote;
dwLength = LoadString (
hMod,
nId,
&szBuffer[3],
SMALL_BUFFER_SIZE);
lstrcat(szBuffer, cszDoubleQuote);
return (LPCTSTR)szBuffer;
}
LPCTSTR
EnquoteString (
IN LPCTSTR szInString
)
/*++
Routine Description:
return the input string wrapped in double quotes
Arguments:
IN LPCTSTR szInString
Return Value:
pointer to string buffer containing a copy of szInString enclosed
in double quotes
--*/
{
static TCHAR szBufArray[NUM_BUFS][SMALL_BUFFER_SIZE];
static DWORD dwIndex;
LPTSTR szBuffer;
dwIndex++;
dwIndex %= NUM_BUFS;
szBuffer = &szBufArray[dwIndex][0];
// clear previous contents
memset (szBuffer, 0, (SMALL_BUFFER_SIZE * sizeof(TCHAR)));
szBuffer[0] = cSpace;
szBuffer[1] = cSpace;
szBuffer[2] = cDoubleQuote;
lstrcpy (&szBuffer[3], szInString);
lstrcat (szBuffer, cszDoubleQuote);
return (LPCTSTR)szBuffer;
}
LONG
GetExpandedFileName (
IN LPTSTR szInFileName,
IN DWORD dwMaxExpandedSize,
OUT LPTSTR szExpandedFileName,
OUT LPTSTR *pFileNamePart
)
/*++
Routine Description:
expands any environment variables in InFileName, then gets the
fully qualified pathname of the result and returns that in the
buffer provided by the caller
Arguments:
IN LPTSTR szInFileName input file string to expand
IN DWORD dwMaxExpandedSize size of output Buffer
OUT LPTSTR szExpandedFileName buffer to recieve expanded name
OUT LPTSTR *pFileNamePart pointer to filename in output buffer
ReturnValue:
WIN32 error status of procedure
--*/
{
LPTSTR szEnvBuffer;
LPTSTR szPathReturn;
LONG lStatus;
DWORD dwSize;
// validate arguments
if ((szInFileName != NULL) &&
(dwMaxExpandedSize != 0)) {
#ifdef WIN32
// allocate working buffers
szEnvBuffer = (LPTSTR)GLOBAL_ALLOC (((dwMaxExpandedSize + 1) * sizeof(TCHAR)));
if (szEnvBuffer != NULL) {
// expand env. strings if any
dwSize = ExpandEnvironmentStrings (
szInFileName,
szEnvBuffer,
(GlobalSize(szEnvBuffer) / sizeof(TCHAR)));
if (dwSize != 0) {
// get full pathname
CLEAR_FIRST_FOUR_BYTES(szExpandedFileName);
if (GetFullPathName (
szEnvBuffer,
dwMaxExpandedSize,
szExpandedFileName,
&szPathReturn) > 0) {
if (pFileNamePart != NULL) {
*pFileNamePart = szPathReturn;
}
lStatus = ERROR_SUCCESS;
} else {
// unable to get full path name
lStatus = ERROR_BAD_PATHNAME;
}
} else {
// error expanding env strings
lStatus = GetMyLastError();
}
} else {
lStatus == ERROR_OUTOFMEMORY;
}
GLOBAL_FREE_IF_ALLOC (szEnvBuffer);
#else // if WIN16
strncpy (szExpandedFileName, szInFileName, (size_t)dwMaxExpandedSize);
lStatus = ERROR_SUCCESS;
// unreferenced vars in WIN 16 mode
dwSize = dwSize;
szEnvBuffer = szEnvBuffer;
szPathReturn = szPathReturn;
#endif
} else {
lStatus = ERROR_INVALID_PARAMETER; // bad argument
}
return lStatus;
}
LONG
CreateDirectoryFromPath (
IN LPCTSTR szPath,
IN LPSECURITY_ATTRIBUTES lpSA
)
/*++
Routine Description:
Creates the directory specified in szPath and any other "higher"
directories in the specified path that don't exist.
Arguments:
IN LPCTSTR szPath
directory path to create (assumed to be a DOS path, not a UNC)
IN LPSECURITY_ATTRIBUTES lpSA
pointer to security attributes argument used by CreateDirectory
Return Value:
TRUE (non-zero) if directory(ies) created
FALSE if error (GetMyLastError to find out why)
--*/
{
LPTSTR szLocalPath;
LPTSTR szEnd;
LONG lReturn = 0L;
szLocalPath = (LPTSTR)GLOBAL_ALLOC (MAX_PATH_BYTES);
if (szLocalPath == NULL) {
SetLastError (ERROR_OUTOFMEMORY);
return 0;
} else {
// so far so good...
SetLastError (ERROR_SUCCESS); // initialize error value to SUCCESS
}
GetExpandedFileName (
(LPTSTR)szPath,
MAX_PATH,
szLocalPath,
NULL);
szEnd = &szLocalPath[3];
if (*szEnd != 0) {
// then there are sub dirs to create
while (*szEnd != 0) {
// go to next backslash
while ((*szEnd != cBackslash) && (*szEnd != 0)) szEnd++;
if (*szEnd == cBackslash) {
// terminate path here and create directory
*szEnd = 0;
if (!CreateDirectory (szLocalPath, lpSA)) {
// see what the error was and "adjust" it if necessary
if (GetMyLastError() == ERROR_ALREADY_EXISTS) {
// this is OK
SetLastError (ERROR_SUCCESS);
} else {
lReturn = 0;
}
} else {
// directory created successfully so update count
lReturn++;
}
// replace backslash and go to next dir
*szEnd++ = cBackslash;
}
}
// create last dir in path now
if (!CreateDirectory (szLocalPath, lpSA)) {
// see what the error was and "adjust" it if necessary
if (GetMyLastError() == ERROR_ALREADY_EXISTS) {
// this is OK
SetLastError (ERROR_SUCCESS);
lReturn++;
} else {
lReturn = 0;
}
} else {
// directory created successfully
lReturn++;
}
} else {
// else this is a root dir only so return success.
lReturn = 1;
}
GLOBAL_FREE_IF_ALLOC (szLocalPath);
return lReturn;
}
BOOL
FileExists (
IN LPCTSTR szPath
)
/*++
Routine Description:
returns TRUE if the file in the path argument exists (NOTE: that
the file is not actually opened to save time, rather the
directory entry is read in order to determine existence)
Arguments:
szPath pointer to filename to look up
Return Value:
TRUE if file exists
FALSE if file not found
--*/
{
BOOL bMediaPresent;
UINT nDriveType;
DWORD dwAttr;
nDriveType = GetDriveTypeFromDosPath((LPTSTR)szPath);
if ((nDriveType == DRIVE_REMOVABLE) || (nDriveType == DRIVE_CDROM)) {
// see if a formatted drive is really there
bMediaPresent = MediaPresent(szPath, TRUE);
} else {
// if drive is not removable, then assume it's there
bMediaPresent = TRUE;
}
// try to get inforation on the file
dwAttr = QuietGetFileAttributes ((LPTSTR)szPath);
if (dwAttr == 0xFFFFFFFF) {
// unable to obtain attributes, so assume it's not there
// or we can't access it
return FALSE;
} else {
// found, so close it and return TRUE
return TRUE;
}
}
LPCTSTR
GetKeyFromIniEntry (
IN LPCTSTR szEntry
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
static TCHAR szReturnBuffer[MAX_PATH];
LPTSTR szSource, szDest;
szSource = (LPTSTR)szEntry;
szDest = &szReturnBuffer[0];
// clear previous contents
memset (szDest, 0, (MAX_PATH * sizeof(TCHAR)));
*szDest = 0;
if (*szSource != 0) {
while ((*szSource != cEqual) && (*szSource != 0)) {
*szDest++ = *szSource++;
}
*szDest = 0;
}
TrimSpaces(szReturnBuffer);
return szReturnBuffer;
}
DWORD
StripQuotes (
IN OUT LPSTR szBuff
)
/*++
Routine Description:
removes all double quote characters (") from the string in the argument.
this function modifies the contents of the buffer passed in the argument
list.
Arguments:
IN OUT LPSTR szBuff
string to removed quote characters from
Return Value:
length of new string in characters
--*/
{
LPSTR szSrcChar;
LPSTR szDestChar;
DWORD dwCharCount;
szSrcChar = szBuff;
szDestChar = szBuff;
dwCharCount = 0;
while (*szSrcChar != '\0') {
if (*szSrcChar != '\"') {
*szDestChar = *szSrcChar;
szDestChar++;
dwCharCount++;
}
szSrcChar++;
}
*szDestChar = '\0';
return dwCharCount;
}
BOOL
GetFilePath (
IN LPCTSTR szFileName,
OUT LPTSTR szPathBuffer
)
/*++
Routine Description:
Scans for the file specified in the argument list.
The OpenFile function looks in the following directories in
the following order for the INF.
1 The current directory.
2 The Windows directory (the directory containing WIN.COM),
whose path the GetWindowsDirectory function retrieves.
3 The Windows system directory (the directory containing
such system files as GDI.EXE), whose path the GetSystemDirectory
function retrieves.
4 The directory containing the executable file for the
current task; the GetModuleFileName function obtains the
path of this directory.
5 The directories listed in the PATH environment variable.
6 The list of directories mapped in a network.
Arguments:
szFileName base filename of file to find
szPathBuffer buffer that application inf file path is written to.
Return Value:
TRUE if a file path is written to szPathBuffer
FALSE if no file is found and szPathBuffer is empty
--*/
{
TOFSTRUCT ofFile;
HFILE hFile;
hFile = OpenFileT (
szFileName,
&ofFile,
OF_SEARCH);
if (hFile != HFILE_ERROR) {
// file found (and opened!) successfully
lstrcpy (szPathBuffer, ofFile.szPathName);
_lclose(hFile); // close file handle for now.
return TRUE;
} else {
*szPathBuffer = 0;
return FALSE;
}
}
BOOL
GetInfPath (
IN HWND hWnd,
IN UINT nFileNameId,
OUT LPTSTR szPathBuffer
)
/*++
Routine Description:
Scans for the INF file described by the string resource ID in the arg
list. The OpenFile function looks in the following directories in
the following order for the INF.
1 The current directory.
2 The Windows directory (the directory containing WIN.COM),
whose path the GetWindowsDirectory function retrieves.
3 The Windows system directory (the directory containing
such system files as GDI.EXE), whose path the GetSystemDirectory
function retrieves.
4 The directory containing the executable file for the
current task; the GetModuleFileName function obtains the
path of this directory.
5 The directories listed in the PATH environment variable.
6 The list of directories mapped in a network.
Arguments:
hWnd Window handle of application main window
nFileNameId ID of string resource containing filename to locate
szPathBuffer buffer that application inf file path is written to.
Return Value:
TRUE if a file path is written to szPathBuffer
FALSE if no file is found and szPathBuffer is empty
--*/
{
return GetFilePath(
GetStringResource (GET_INSTANCE(hWnd), nFileNameId),
szPathBuffer);
}
BOOL
DrawRaisedShading (
IN LPRECT prShadeWnd,
IN LPPAINTSTRUCT ps,
IN LONG lDepth,
IN HPEN hpenHighlight,
IN HPEN hpenShadow
)
{
LONG lLineDepth;
RECT rWnd; // local window rectangle dimensions
rWnd = *prShadeWnd; // make local copy of rectangle
// adjust rectangle to fit within client area
rWnd.right -= 1;
rWnd.bottom -= 1;
if ((lDepth > 0) &&
(lDepth < (rWnd.bottom / 2)) &&
(lDepth < (rWnd.right / 2))) {
// draw shading line
for (lLineDepth = 0; lLineDepth < lDepth; lLineDepth++) {
// start at bottom left corner and draw highlight
SelectObject (ps->hdc, hpenHighlight);
MoveToEx (ps->hdc, rWnd.left, rWnd.bottom, NULL);
LineTo (ps->hdc, rWnd.left, rWnd.top);
LineTo (ps->hdc, rWnd.right, rWnd.top);
// draw shadow lines
SelectObject (ps->hdc, hpenShadow);
LineTo (ps->hdc, rWnd.right, rWnd.bottom);
LineTo (ps->hdc, rWnd.left-1, rWnd.bottom);
// shrink rectangle for next iteration
rWnd.top += 1;
rWnd.left += 1;
if (rWnd.left < rWnd.right) rWnd.right -= 1;
if (rWnd.top < rWnd.bottom) rWnd.bottom -= 1;
}
return TRUE;
} else {
// depth is bigger than window
return FALSE;
}
}
BOOL
DrawSeparatorLine (
IN LPRECT lprLine,
IN LPPAINTSTRUCT ps,
IN HPEN hpenLine
)
{
SelectObject (ps->hdc, hpenLine);
return Rectangle (ps->hdc,
lprLine->left,
lprLine->top,
lprLine->right,
lprLine->bottom);
}
DWORD
GetFileSizeFromPath (
LPCTSTR szPath
)
/*++
Routine Description:
returns the size of the file specified in szPath (if it exists)
(up to 4 GB)
returns 0 byte size if:
the file could not be found
the file is 0 bytes long
Arguments:
szPath path and name of file to query
Return Value:
see description
--*/
{
HANDLE hFile;
DWORD dwSize, dwHiSize;
if (FileExists(szPath)) {
hFile = CreateFile(szPath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE) {
dwSize = GetFileSize (hFile, &dwHiSize);
if (dwSize == 0xFFFFFFFF) {
// an error so return 0
dwSize = 0;
} else if (dwHiSize > 0) {
// file is > 4GB so return Max Int
dwSize = 0xFFFFFFFF;
} else {
// file size was returned and <= 4GB so return size
}
CloseHandle (hFile);
return dwSize;
} else {
return 0; // unable to open file
}
} else {
return 0; // file not found
}
}