|
|
/* 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 <windows.h>
#pragma hdrstop
#include "stdtyp.h"
#include "mc.h"
#include "sf.h"
#include "tdll.h"
#include "sess_ids.h"
#include <tdll\assert.h>
#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: * */
|