/* File: D:\WACKER\tdll\file_msc.c (Created: 26-Dec-1993) * * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI * All rights reserved * * $Revision: 11 $ * $Date: 7/08/02 6:41p $ */ #include #pragma hdrstop #include "stdtyp.h" #include "mc.h" #include "sf.h" #include "tdll.h" #include "sess_ids.h" #include #include "session.h" #include "open_msc.h" #include "htchar.h" #include "file_msc.h" #include "file_msc.hh" /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * * F I L E _ M S C . C * * This file contains functions that are needed to deal with files, names of * files, lists of files and just about anything else about files. * *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ STATIC_FUNC int fmBFLinternal(void **pData, int *pCnt, LPCTSTR pszName, int nSubdir, LPCTSTR pszDirectory); /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * CreateFilesDirsHdl * * DESCRIPTION: * This function is called to create the files and directory handle. * * PARAMETERS: * hSession -- the session handle * * RETURNS: * A pointer to the HFILES handle. */ HFILES CreateFilesDirsHdl(const HSESSION hSession) { FD_DATA *pFD; int nRet; pFD = (FD_DATA *)malloc(sizeof(FD_DATA)); assert(pFD); if (pFD) { memset(pFD, 0, sizeof(FD_DATA)); nRet = InitializeFilesDirsHdl(hSession, (HFILES)pFD); if (nRet) goto CFDHexit; } return (HFILES)pFD; CFDHexit: if (pFD) { if (pFD->pszInternalSendDirectory) { free(pFD->pszInternalSendDirectory); pFD->pszInternalSendDirectory = NULL; } if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = NULL; } if (pFD->pszInternalRecvDirectory) { free(pFD->pszInternalRecvDirectory); pFD->pszInternalRecvDirectory = NULL; } if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = NULL; } free(pFD); pFD = NULL; } return (HFILES)0; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * InitializeFilesDirs * * DESCRIPTION: * This function is called to put the files and directorys handle into a * known and safe state. * * PARAMETERS: * hSession -- the session handle * hFile -- the files and directory handle * * RETURNS: * ZERO if everything is OK, otherwise an error code. */ INT InitializeFilesDirsHdl(const HSESSION hSession, HFILES hFile) { FD_DATA *pFD; LPTSTR pszSname; LPTSTR pszRname; int nSize; TCHAR acDir[FNAME_LEN]; pFD = (FD_DATA *)hFile; assert(pFD); pszSname = pszRname = (LPTSTR)0; if (pFD) { if (pFD->pszInternalSendDirectory) { free(pFD->pszInternalSendDirectory); pFD->pszInternalSendDirectory = NULL; } if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = (LPTSTR)0; } if (pFD->pszInternalRecvDirectory) { free(pFD->pszInternalRecvDirectory); pFD->pszInternalRecvDirectory = NULL; } if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = (LPTSTR)0; } memset(pFD, 0, sizeof(FD_DATA)); pFD->hSession = hSession; //Changed to use working path rather than current path - mpt 8-18-99 if ( !GetWorkingDirectory( acDir, FNAME_LEN ) ) { GetCurrentDirectory(FNAME_LEN, acDir); } nSize = StrCharGetByteCount(acDir) + sizeof(TCHAR); pszSname = malloc(nSize); if (pszSname == (LPTSTR)0) goto IFDexit; pszRname = malloc(nSize); if (pszRname == (LPTSTR)0) goto IFDexit; if (pFD->pszInternalSendDirectory) { free(pFD->pszInternalSendDirectory); pFD->pszInternalSendDirectory = NULL; } pFD->pszInternalSendDirectory = pszSname; StrCharCopyN(pFD->pszInternalSendDirectory, acDir, nSize); if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = (LPTSTR)0; } if (pFD->pszInternalRecvDirectory) { free(pFD->pszInternalRecvDirectory); pFD->pszInternalRecvDirectory = NULL; } pFD->pszInternalRecvDirectory = pszRname; StrCharCopyN(pFD->pszInternalRecvDirectory, acDir, nSize); if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = (LPTSTR)0; } } return 0; IFDexit: if (pszSname) { free(pszSname); pszSname = NULL; } if (pszRname) { free(pszRname); pszRname = NULL; } return FM_ERR_NO_MEM; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * LoadFilesDirs * * DESCRIPTION: * This function is called to read whatever values are in the session file * into the files and directorys handle * * PARAMETERS: * hFile -- the files and directory handle * * RETURNS: * ZERO if everything is OK, otherwise an error code. */ INT LoadFilesDirsHdl(HFILES hFile) { INT nRet = 0; FD_DATA *pFD; long lSize; LPTSTR pszStr; pFD = (FD_DATA *)hFile; assert(pFD); if (pFD == (FD_DATA *)0) return FM_ERR_BAD_HANDLE; InitializeFilesDirsHdl(pFD->hSession, hFile); if (nRet == 0) { lSize = 0; sfGetSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_SEND_DIR, &lSize, NULL); if (lSize != 0) { pszStr = (LPTSTR)malloc(lSize); if (pszStr) { sfGetSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_SEND_DIR, &lSize, pszStr); if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = NULL; } pFD->pszTransferSendDirectory = pszStr; } else { nRet = FM_ERR_NO_MEM; } } } if (nRet == 0) { lSize = 0; sfGetSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_RECV_DIR, &lSize, NULL); if (lSize != 0) { pszStr = (LPTSTR)malloc(lSize); if (pszStr) { sfGetSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_RECV_DIR, &lSize, pszStr); if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = NULL; } pFD->pszTransferRecvDirectory = pszStr; } else { nRet = FM_ERR_NO_MEM; } } } return nRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * DestroyFilesDirsHdl * * DESCRIPTION: * This function is called to free all the memory that is in a Files and * Directorys handle. Gone. History. Toast. * * PARAMETERS: * hFile -- the files and directorys handle * * RETURNS: * ZERO if everything is OK, otherwise an error code. */ INT DestroyFilesDirsHdl(const HFILES hFile) { INT nRet = 0; FD_DATA *pFD; pFD = (FD_DATA *)hFile; assert(pFD); if (pFD == (FD_DATA *)0) return FM_ERR_BAD_HANDLE; if (pFD->pszInternalSendDirectory) { free(pFD->pszInternalSendDirectory); pFD->pszInternalSendDirectory = NULL; } if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = NULL; } if (pFD->pszInternalRecvDirectory) { free(pFD->pszInternalRecvDirectory); pFD->pszInternalRecvDirectory = NULL; } if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = NULL; } free(pFD); pFD = NULL; return 0; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * SaveFilesDirsHdl * * DESCRIPTION: * This function is called to save out to the session file all of the data * that has changed in the Files and Directorys handle. * * PARAMETERS: * hFile -- the files and directorys handle * * RETURNS: * ZERO if everything is OK, otherwise an error code. */ INT SaveFilesDirsHdl(const HFILES hFile) { FD_DATA *pFD; long lSize; pFD = (FD_DATA *)hFile; assert(pFD); if (pFD == (FD_DATA *)0) return FM_ERR_BAD_HANDLE; if (pFD->pszTransferSendDirectory) { lSize = StrCharGetByteCount(pFD->pszTransferSendDirectory) + 1; sfPutSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_SEND_DIR, lSize, pFD->pszTransferSendDirectory); } if (pFD->pszTransferRecvDirectory) { lSize = StrCharGetByteCount(pFD->pszTransferRecvDirectory) + 1; sfPutSessionItem(sessQuerySysFileHdl(pFD->hSession), SFID_XFR_RECV_DIR, lSize, pFD->pszTransferRecvDirectory); } return 0; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * filesQuerySendDirectory * * DESCRIPTION: * This function returns a pointer to the current default transfer send * directory. * * PARAMETERS: * hFile -- the files and directorys handle * * RETURNS: * A pointer to the current default transfer send directory * */ LPCTSTR filesQuerySendDirectory(HFILES hFile) { FD_DATA *pFD; pFD = (FD_DATA *)hFile; assert(pFD); assert(pFD->pszInternalSendDirectory); if (pFD->pszTransferSendDirectory == (LPTSTR)0) return (LPCTSTR)pFD->pszInternalSendDirectory; if (StrCharGetStrLength(pFD->pszTransferSendDirectory) == 0) return (LPCTSTR)pFD->pszInternalSendDirectory; return (LPCTSTR)pFD->pszTransferSendDirectory; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * filesQueryRecvDirectory * * DESCRIPTION: * This function returns a pointer to the current default transfer recv * directory. * * PARAMETERS: * hFile -- the files and directorys handle * * RETURNS: * A pointer to the current default recv directory * */ LPCTSTR filesQueryRecvDirectory(HFILES hFile) { FD_DATA *pFD; pFD = (FD_DATA *)hFile; assert(pFD); assert(pFD->pszInternalRecvDirectory); if (pFD->pszTransferRecvDirectory == (LPTSTR)0) return (LPCTSTR)pFD->pszInternalRecvDirectory; if (StrCharGetStrLength(pFD->pszTransferRecvDirectory) == 0) return (LPCTSTR)pFD->pszInternalRecvDirectory; return (LPCTSTR)pFD->pszTransferRecvDirectory; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * filesSetSendDirectory * * DESCRIPTION: * This function is called to change (maybe) the current default sending * directory. * * PARAMETERS: * hFile -- the files and directorys handle * pszDir -- pointer to the new directory path * * RETURNS: * Nothing. * */ VOID filesSetSendDirectory(HFILES hFile, LPCTSTR pszDir) { LPTSTR pszTmp; FD_DATA *pFD; int pszTmpLen; pFD = (FD_DATA *)hFile; assert(pFD); pszTmpLen = StrCharGetByteCount(pszDir) + 1; pszTmp = (LPTSTR)malloc(pszTmpLen); assert(pszTmp); if (pszTmp == NULL) return; StrCharCopyN(pszTmp, pszDir, pszTmpLen); if (pFD->pszTransferSendDirectory) { free(pFD->pszTransferSendDirectory); pFD->pszTransferSendDirectory = NULL; } pFD->pszTransferSendDirectory = pszTmp; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * filesSetRecvDirectory * * DESCRIPTION: * This function is called to change (maybe) the current default receiving * directory. * * PARAMETERS: * hFile -- the files and directorys handle * pszDir -- pointer to the new directory path * * RETURNS: * Nothing. * */ VOID filesSetRecvDirectory(HFILES hFile, LPCTSTR pszDir) { LPTSTR pszTmp; FD_DATA *pFD; int pszTmpLen; pFD = (FD_DATA *)hFile; assert(pFD); pszTmpLen = StrCharGetByteCount(pszDir) + 1; pszTmp = (LPTSTR)malloc(pszTmpLen); assert(pszTmp); if (pszTmp == NULL) return; StrCharCopyN(pszTmp, pszDir, pszTmpLen); if (pFD->pszTransferRecvDirectory) { free(pFD->pszTransferRecvDirectory); pFD->pszTransferRecvDirectory = NULL; } pFD->pszTransferRecvDirectory = pszTmp; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * fileBuildFileList * * DESCRIPTION: * This function is called to build a list of all the files that match * a given mask. * * PARAMETERS: * pData -- pointer to where to store the pointer to the data block * pCnt -- pointer to where the item count is returned * pszName -- file name mask used to build list * nSubdir -- if TRUE, search subdirectorys * pszDirectory -- directory to start search from * * RETURNS: * ZERO if everything is OK, otherwise an error code * */ int fileBuildFileList(void **pData, int *pCnt, LPCTSTR pszName, int nSubdir, LPCTSTR pszDirectory) { int nRet = 0; void *pLocalData = NULL; int nLocalCnt = 0; LPTSTR pszStr; LPTSTR *pszArray; TCHAR pszLocalDirectory[FNAME_LEN]; /* Make sure the directory string terminates correctly */ StrCharCopyN(pszLocalDirectory, pszDirectory, FNAME_LEN); pszStr = StrCharLast(pszLocalDirectory); if (*pszStr != TEXT('\\')) { /* Make sure the last character is a "\" */ StrCharCat(pszStr, TEXT("\\")); } pLocalData = malloc(sizeof(LPTSTR) * FM_CHUNK_SIZE); if (pLocalData == NULL) nRet = FM_ERR_NO_MEM; if (nRet == 0) { nRet = fmBFLinternal(&pLocalData, &nLocalCnt, pszName, nSubdir, pszLocalDirectory); } if (nRet == 0) { /* OK, no problem */ *pData = pLocalData; *pCnt = nLocalCnt; } else { /* Error, clean up first and then go away */ if (pLocalData) { pszArray = (LPTSTR *)pLocalData; while (--nLocalCnt >= 0) { free(*pszArray++); *pszArray = NULL; } free(pLocalData); pLocalData = NULL; } } return nRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * fmBFLinternal * * DESCRIPTION: * This is the internal function that the previous function calls to do the * actual work. * * PARAMETERS: * The same as above. * * RETURNS: * ZERO if everything is OK, otherwise an error code * */ STATIC_FUNC int fmBFLinternal(void **pData, int *pCnt, LPCTSTR pszName, int nSubdir, LPCTSTR pszDirectory) { int nRet = 0; int nSize; WIN32_FIND_DATA stF; HANDLE sH = INVALID_HANDLE_VALUE; LPTSTR pszBuildName; LPTSTR pszStr; LPTSTR *pszArray; pszBuildName = (LPTSTR)malloc(FNAME_LEN * sizeof(TCHAR)); if (pszBuildName == NULL) { nRet = FM_ERR_NO_MEM; goto fmBFLexit; } StrCharCopyN(pszBuildName, pszDirectory, FNAME_LEN); StrCharCat(pszBuildName, pszName); sH = FindFirstFile(pszBuildName, &stF); if (sH != INVALID_HANDLE_VALUE) { /* Handle is OK, we have something to work on */ do { /* Is it a directory ? If it is, skip it until later */ if (stF.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; /* Must be a file. */ if (stF.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) continue; if (stF.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) continue; /* Add the file to the list */ if ((*pCnt > 0) && ((*pCnt % FM_CHUNK_SIZE) == 0)) { TCHAR* pTemppData = *pData; /* realloc the chunk */ nSize = *pCnt + FM_CHUNK_SIZE; pTemppData = (TCHAR*)realloc(*pData, nSize * sizeof(LPTSTR) ); if (pTemppData == NULL) { nRet = FM_ERR_NO_MEM; goto fmBFLexit; } else { *pData = pTemppData; } } nSize = StrCharGetByteCount(pszDirectory) + StrCharGetByteCount(stF.cFileName); nSize += 1; nSize *= sizeof(TCHAR); pszStr = (LPTSTR)malloc(nSize); if (pszStr == (LPTSTR)0) { nRet = FM_ERR_NO_MEM; goto fmBFLexit; } StrCharCopyN(pszStr, pszDirectory, nSize); StrCharCat(pszStr, stF.cFileName); pszArray = (LPTSTR *)*pData; pszArray[*pCnt] = pszStr; *pCnt += 1; } while (FindNextFile(sH, &stF)); FindClose(sH); sH = INVALID_HANDLE_VALUE; } else { nRet = FM_ERR_BAD_HANDLE; goto fmBFLexit; } if (nSubdir) { StrCharCopyN(pszBuildName, pszDirectory, FNAME_LEN); StrCharCat(pszBuildName, TEXT("*.*")); /* This may need to change */ sH = FindFirstFile(pszBuildName, &stF); if (sH != INVALID_HANDLE_VALUE) { /* Handle is OK, we have something to work on */ do { /* Is it a directory ? If it is, go recursive */ if (stF.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (StrCharCmp(stF.cFileName, TEXT(".")) == 0) continue; if (StrCharCmp(stF.cFileName, TEXT("..")) == 0) continue; StrCharCopyN(pszBuildName, pszDirectory, FNAME_LEN); StrCharCat(pszBuildName, stF.cFileName); StrCharCat(pszBuildName, TEXT("\\")); fmBFLinternal(pData, pCnt, pszName, nSubdir, pszBuildName); } } while (FindNextFile(sH, &stF)); FindClose(sH); sH = INVALID_HANDLE_VALUE; } else { nRet = FM_ERR_BAD_HANDLE; goto fmBFLexit; } } fmBFLexit: /* NOTE: all returns must come thru here */ if (sH != INVALID_HANDLE_VALUE) FindClose(sH); if (pszBuildName) { free(pszBuildName); pszBuildName = NULL; } return nRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * FUNCTION: * fileFinalizeName * * DESCRIPTION: * This function takes a possibly incomplete file name and trys to convert * it to a fully qualified name, if possible, based upon the mode request. * * PARAMETERS: * hSession -- the almost universal session handle * pszOldname -- a pointer to the old name string * pszOlddir -- a pointer to an optional path * pszNewname -- a pointer to where the new string should go * nMode -- what should be done to the string, currently ignored * * RETURNS: * TRUE if a conversion was completed and copied, FALSE if nothing was copied. */ int fileFinalizeName(LPTSTR pszOldname, LPTSTR pszOlddir, LPTSTR pszNewname, const size_t cb) { TCHAR *pachFile; TCHAR achCurDir[MAX_PATH]; assert(cb); assert(pszNewname); assert(pszOldname); achCurDir[0] = TEXT('\0'); // If we're given a directory, save the current directory and // set the current directory to the one given. // if (pszOlddir && *pszOlddir != TEXT('\0')) { if (GetCurrentDirectory(sizeof(achCurDir), achCurDir) == 0) { assert(0); return FALSE; } if (SetCurrentDirectory(pszOlddir) == FALSE) { assert(0); return FALSE; } } // This function does the correct job of building a full path // name and works with UNC names. // if (GetFullPathName(pszOldname, cb, pszNewname, &pachFile) == 0) { assert(0); return FALSE; } // Restore the current directory we saved above. // if (achCurDir[0] != TEXT('\0')) { if (SetCurrentDirectory(achCurDir) == FALSE) { assert (0); return FALSE; } } return TRUE; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * FUNCTION: * mfFinalizeDIR * * DESCRIPTION: * This function is called to clean up a directory name. At the present time * it doesn't do very much. * * PARAMETERS: * hSession -- the almost universal session handle * pszOldname -- a pointer to the old directory name * pszNewname -- a pointer to where the new string should go * * RETURNS: * TRUE if a copy was completed, FALSE if nothing was copied. */ int fileFinalizeDIR(HSESSION hSession, LPTSTR pszOldname, LPTSTR pszNewname) { LPTSTR pszPtr; LPTSTR pszFoo; StrCharCopyN(pszNewname, pszOldname, FNAME_LEN); pszPtr = StrCharNext(pszNewname); pszFoo = StrCharNext(pszPtr); if ((StrCharGetStrLength(pszNewname) == 2) && (*pszPtr == TEXT(':'))) { StrCharCat(pszNewname, TEXT("\\")); } else if ((StrCharGetStrLength(pszNewname) == 3) && (*pszPtr == TEXT(':')) && (*pszFoo == TEXT('\\'))) { /* Do nothing */ } else { pszPtr = StrCharLast(pszNewname); if (*pszPtr == TEXT('\\')) *pszPtr = TEXT('\0'); } return 1; } #if defined(BMP_FROM_FILE) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * fileReadBitmapFromFile * * DESCRIPTION: * This function takes a filename, opens the file and attempts to interpret * the file as a bitmap file, turning it into a bitmap. * * PARAMETERS: * hDC -- device context used to create the bitmap * pszName -- the name of the file * * RETURNS: * A bitmap handle or NULL. * */ HBITMAP fileReadBitmapFromFile(HDC hDC, LPTSTR pszName, int fCmp) { HBITMAP hBmp = (HBITMAP)0; DWORD dwRead; DWORD dwSize; HANDLE hfbm; int hcbm; OFSTRUCT stOF; BITMAPFILEHEADER bmfh; BITMAPINFOHEADER bmih; BITMAPINFO *lpbmi; VOID *lpvBits; lpbmi = NULL; lpvBits = NULL; if (fCmp) { memset(&stOF, 0, sizeof(OFSTRUCT)); stOF.cBytes = sizeof(OFSTRUCT); hcbm = LZOpenFile(pszName, &stOF, OF_READ); if (hcbm < 0) return hBmp; } else { hfbm = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if (hfbm == INVALID_HANDLE_VALUE) return hBmp; } /* Retrieve the BITMAPFILEHEADER structure */ memset(&bmfh, 0, sizeof(BITMAPFILEHEADER)); if (fCmp) { dwRead = 0; dwRead = LZRead(hcbm, (unsigned char *)&bmfh, sizeof(BITMAPFILEHEADER)); /* this is necessary because of a garbage return value */ dwRead = sizeof(BITMAPFILEHEADER); } else { ReadFile(hfbm, &bmfh, sizeof(BITMAPFILEHEADER), &dwRead, NULL); } if (dwRead != sizeof(BITMAPFILEHEADER)) goto fError; /* Retrieve the BITMAPINFOHEADER structure */ memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); if (fCmp) { dwRead = 0; dwRead = LZRead(hcbm, (unsigned char *)&bmih, sizeof(BITMAPINFOHEADER)); /* this is necessary because of a garbage return value */ dwRead = sizeof(BITMAPINFOHEADER); } else { ReadFile(hfbm, &bmih, sizeof(BITMAPINFOHEADER), &dwRead, NULL); } if (dwRead != sizeof(BITMAPINFOHEADER)) goto fError; /* allocate space for the BITMAPINFO structure */ dwSize = sizeof(BITMAPINFOHEADER) + ((1 << bmih.biBitCount) * sizeof(RGBQUAD)); lpbmi = malloc(dwSize); if (lpbmi == NULL) goto fError; /* load BITMAPINFOHEADER into the BITMAPINFO structure */ lpbmi->bmiHeader.biSize = bmih.biSize; lpbmi->bmiHeader.biWidth = bmih.biWidth; lpbmi->bmiHeader.biHeight = bmih.biHeight; lpbmi->bmiHeader.biPlanes = bmih.biPlanes; lpbmi->bmiHeader.biBitCount = bmih.biBitCount; lpbmi->bmiHeader.biCompression = bmih.biCompression; lpbmi->bmiHeader.biSizeImage = bmih.biSizeImage; lpbmi->bmiHeader.biXPelsPerMeter = bmih.biXPelsPerMeter; lpbmi->bmiHeader.biYPelsPerMeter = bmih.biYPelsPerMeter; lpbmi->bmiHeader.biClrUsed = bmih.biClrUsed; lpbmi->bmiHeader.biClrImportant = bmih.biClrImportant; /* read the color table */ dwSize = (1 << bmih.biBitCount) * sizeof(RGBQUAD); if (fCmp) { dwRead = 0; dwRead = LZRead(hcbm, (unsigned char *)lpbmi->bmiColors, dwSize); /* this is necessary because of a garbage return value */ dwRead = dwSize; } else { ReadFile(hfbm, lpbmi->bmiColors, dwSize, &dwRead, NULL); } if (dwSize != dwRead) goto fError; /* allocate memory for the bitmap data */ dwSize = bmfh.bfSize - bmfh.bfOffBits; lpvBits = malloc(dwSize); if (lpvBits == NULL) goto fError; /* read in the bitmap data */ if (fCmp) { dwRead = 0; dwRead = LZRead(hcbm, lpvBits, dwSize); /* this is necessary because of a garbage return value */ dwRead = dwSize; } else { ReadFile(hfbm, lpvBits, dwSize, &dwRead, NULL); } if (dwSize != dwRead) goto fError; /* create the bitmap handle */ hBmp = CreateDIBitmap(hDC, &bmih, CBM_INIT, lpvBits, lpbmi, DIB_RGB_COLORS); /* either it worked or it didn't */ fError: /* Clean up everything here */ if (lpbmi != NULL) { free(lpbmi); lpbmi = NULL; } if (lpvBits != NULL) { free(lpvBits); lpvBits = NULL; } if (fCmp) { LZClose(hcbm); } else { CloseHandle(hfbm); } return hBmp; } #endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: GetFileSizeFromName * * DESCRIPTION: * Returns the size of a named file. (The GetFileSize Win32 API call * requires the file to be open, this doesn't). * Note: the WIN32 API is structured to support 64 bits file size values * so this may need to be updated at some point. * * PARAMETERS: * pszName -- the name of the file. * pulFileSize -- Pointer to the var. that receives the file size. * (If NULL, this function can be used to test for the * existense of a file). * * RETURNS: * TRUE if file is found, FALSE if not */ int GetFileSizeFromName(TCHAR *pszName, unsigned long * const pulFileSize) { WIN32_FIND_DATA stFData; HANDLE hFind; int fReturnValue = FALSE; hFind = FindFirstFile(pszName, &stFData); if (hFind != INVALID_HANDLE_VALUE) { DWORD dwMask; /* This is just a guess. If you need to change it, do so. */ dwMask = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM; if ((stFData.dwFileAttributes & dwMask) == 0) { fReturnValue = TRUE; // Strictly speaking, file sizes can now be 64 bits. assert(stFData.nFileSizeHigh == 0); if (pulFileSize) *pulFileSize = (unsigned long)stFData.nFileSizeLow; } FindClose(hFind); } return fReturnValue; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * SetFileSize * * DESCRIPTION: * * PARAMETERS: * * RETURNS: */ int SetFileSize(const TCHAR *pszName, unsigned long ulFileSize) { HANDLE hFile; int nRet = -1; /* Yes, we need to open the file */ hFile = CreateFile(pszName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return -1; /* No such file */ if (SetFilePointer(hFile, ulFileSize, NULL, FILE_BEGIN) == ulFileSize) { if (SetEndOfFile(hFile)) nRet = 0; } CloseHandle(hFile); return nRet; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * ValidateFileName * * DESCRIPTION: * Determine whether a file pathname is valid by attempting to open it. * * PARAMETERS: * * LPSTR pszName - the name/pathname * * RETURNS: * * 0, if a file with the specified name could not be opened/created, * 1, if it could. * */ int ValidateFileName(LPSTR pszName) { HANDLE hfile = 0; if (GetFileSizeFromName(pszName, NULL)) { hfile = CreateFile(pszName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); } else { hfile = CreateFile(pszName, GENERIC_READ, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL); } if(hfile != INVALID_HANDLE_VALUE) { CloseHandle(hfile); return(1); } else { return(0); } } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= * FUNCTION: * * DESCRIPTION: * * PARAMETERS: * * RETURNS: * */