|
|
/* File: D:\WACKER\tdll\sf.c (Created: 27-Nov-1993)
* * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI * All rights reserved * * $Revision: 16 $ * $Date: 3/15/02 12:27p $ */
#include <windows.h>
#include <shlobj.h>
#pragma hdrstop
#include <stdio.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "stdtyp.h"
#include "tdll.h"
#include "htchar.h"
#include "sf.h"
#include "mc.h"
typedef int int32;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* * DATA SECTION * * This section contains all of the static data that the DLL uses. Once this * data is exhausted, the DLL can do no more. It just returns errors. This * means that it is important to close or release any and all session files * that get opened. * */
struct stDllSessionFileIndexItem { int32 uIndex; /* Index of the item */ int32 dwSize; /* Size of the item */ int32 dwOffset; /* Offset into data block of the item */ };
typedef struct stDllSessionFileIndexItem stDSII; typedef stDSII *pstDSII;
struct stDllSessionFilePointer { int uBusy; /* TRUE means item is in use */ int fOpen; /* TRUE means open session file */ int uChanged; /* TRUE means something is different */
TCHAR *hFilename; /* Memory containing the file name */
/* These make up the index */ int uItemCount; /* Current items in the index */ int uItemsAlloc; /* Max items in current space */ pstDSII hIndex; /* Memory allocated for index */
/* This is the data segment */ int dwDataUsed; /* Amount used in data block */ int dwDataSize; /* Current sizeof the data block */ BYTE *hData; /* Memory allocated for file data */ };
typedef struct stDllSessionFilePointer stDSFP; typedef stDSFP *pstDSFP;
#define ROUND_UP(x) ((x+0xFFFL)&(~0x0FFFL))
// used for testing #define ROUND_UP(x) ((x+0x3F)&(~0x03F))
#define SESS_FILE_MAX 64
static stDSFP asSessionFiles[SESS_FILE_MAX];
#define HDR_SIZE 256
TCHAR pszHdr[HDR_SIZE] = { TEXT("HyperTerminal 1.0 -- HyperTerminal data file\r\n") TEXT("Please do not attempt to modify this file directly.\r\n") TEXT("\r\n\r\n") TEXT("\x1A") };
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfAddToIndex * * DESCRIPTION: * * ARGUEMENTS: * * RETURNS: * The offset of the item in the index array, or -1. */ int32 sfAddToIndex(const int uNdx, const int32 sID, const int32 dwSZ, const int32 dwOffset) { int nRv = -1; int nCnt; int low, mid, high; int found; pstDSFP pD; pstDSII pI; pstDSII pIx; pstDSII pIy;
pD = &asSessionFiles[uNdx];
if (pD->uItemCount >= pD->uItemsAlloc) { #if defined(DEBUG_OUTPUT)
OutputDebugString("Index expanded\r\n"); #endif
/*
* We need to get a bigger chunk of memory */ if (pD->hIndex == 0) { pD->uItemsAlloc = 64; pD->hIndex = (pstDSII)malloc(sizeof(stDSII) * 64); } else { int newSize = pD->uItemsAlloc * 2; stDSII * pTemphIndex = (pstDSII) realloc(pD->hIndex, (size_t)newSize * sizeof(stDSII));
if (pTemphIndex == NULL) { return SF_ERR_MEMORY_ERROR; } else { pD->uItemsAlloc = newSize; pD->hIndex = pTemphIndex; } } }
if (pD->hData == 0) { pD->hData = (BYTE *)malloc(ROUND_UP(4096)); memset(pD->hData, 0, HDR_SIZE); pD->dwDataSize = ROUND_UP(4096); pD->dwDataUsed = HDR_SIZE; }
/*
* Find where the item goes */ pI = pD->hIndex;
found = FALSE; pIx = 0; low = 0; high = pD->uItemCount - 1; mid = high/2;
if (pD->uItemCount > 0) { while (low <= high) { mid = (low + high) / 2; pIx = pI + mid;
if (sID < pIx->uIndex) { high = mid - 1; } else if (sID > pIx->uIndex) { low = mid + 1; } else { /* found a match */ found = TRUE; break; } } }
if (found) { if (dwSZ != 0) { /*
* Special case. Preserve the old values so that we can * adjust the data section for the replacement value. */ pIx->dwSize = dwSZ; pIx->dwOffset = dwOffset; } nRv = mid; } else { /*
* The problem with a binary search is that it is unclear where * you are if no match occurs. So we do it the old way. */ pIx = pI; nCnt = 0; for (;;) { /* TODO: switch to binary search */ if (nCnt >= pD->uItemCount) { /*
* We have gone past the end of the list */ pIx->uIndex = sID; pIx->dwSize = dwSZ; pIx->dwOffset = dwOffset; nRv = nCnt; break; } else if (pIx->uIndex >= sID) { if (pIx->uIndex > sID) { /*
* Slide the remaining items down by one */
pIy = pI + pD->uItemCount; while (pIy > pIx) { *pIy = *(pIy - 1); pIy -= 1; }
#if 0
/* Don, would this work better? */
_fmemmove(pIx+1, pIx, (pD->uItemCount - nCnt) * sizeof(stDSII));
#endif
pIx->uIndex = sID; pIx->dwSize = dwSZ; pIx->dwOffset = dwOffset; } else /* == */ { if (dwSZ != 0) { /*
* Special case. Preserve the old values so that we can * adjust the data section for the replacement value. */ pIx->dwSize = dwSZ; pIx->dwOffset = dwOffset; } pD->uItemCount -= 1; }
nRv = (int)(pIx - pI); break; } pIx += 1; nCnt += 1; } pD->uItemCount += 1; }
return nRv; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: * CreateSysFileHdl * * DESCRIPTION: * Creates a session file handle * * ARGUMENTS: * none * * RETURNS: * SF_HANDLE or < 0 for error * */ SF_HANDLE CreateSysFileHdl(void) { int uNdx;
for (uNdx = 0; uNdx < SESS_FILE_MAX; uNdx += 1) { /*
* See if an unused slot is available */ if (asSessionFiles[uNdx].uBusy == 0) { memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP)); asSessionFiles[uNdx].uBusy = TRUE; return (uNdx + 1); } }
return SF_ERR_BAD_PARAMETER; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfOpenSessionFile * * DESCRIPTION: * This function is called to build an in memory data structure that * represents the data currently in a session file. If the file specified * is not a valid session file, an error is returned. * * ARGUEMENTS: * TCHAR *pszName -- the name of the session file. * * RETURNS: * 0 or an error code < 0; */ int sfOpenSessionFile(const SF_HANDLE sF, const TCHAR *pszName) { int uRv = 0; int uNdx = sF - 1; unsigned long uSize, uSize1; TCHAR *pszStr = NULL; TCHAR *pszPtr = NULL; HANDLE hFile; int sID, sOldID; int32 dwSZ; int nOrderOK; DWORD dw;
if (uNdx >= SESS_FILE_MAX) { uRv = SF_ERR_BAD_PARAMETER; goto OSFexit; }
if (asSessionFiles[uNdx].uBusy == 0) { uRv = SF_ERR_BAD_PARAMETER; goto OSFexit; }
if (asSessionFiles[uNdx].fOpen) { uRv = SF_ERR_FILE_ACCESS; goto OSFexit; }
if (pszName && (StrCharGetStrLength(pszName) > 0)) { int nRv = -1; pstDSFP pD; pstDSII pI; pstDSII pIx;
/*
* Do everything that can be done with a name */ asSessionFiles[uNdx].hFilename = (TCHAR *)malloc(FNAME_LEN * sizeof(TCHAR));
if (asSessionFiles[uNdx].hFilename == NULL) goto OSFexit;
pszStr = asSessionFiles[uNdx].hFilename;
TCHAR_Fill(pszStr, TEXT('\0'), FNAME_LEN); StrCharCopyN(pszStr, (LPTSTR)pszName, FNAME_LEN); pszStr = NULL;
/*
* Try to open file. If we can then proceed */ hFile = CreateFile(pszName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
/*
* Get the size of the file */ if (hFile == INVALID_HANDLE_VALUE) { asSessionFiles[uNdx].fOpen = TRUE; uRv = SF_ERR_FILE_ACCESS; return uRv; } else { /*
* Allocate a data block */ asSessionFiles[uNdx].fOpen = TRUE;
uSize = GetFileSize(hFile, &dw); uSize = ROUND_UP(uSize); asSessionFiles[uNdx].dwDataSize = (int)uSize; asSessionFiles[uNdx].dwDataUsed = 0; asSessionFiles[uNdx].hData = (BYTE *)malloc(uSize);
if (asSessionFiles[uNdx].hData == 0) { uRv = SF_ERR_MEMORY_ERROR; goto OSFexit; }
pszStr = (TCHAR *)asSessionFiles[uNdx].hData; pszPtr = pszStr; memset(pszStr, 0, uSize * sizeof(TCHAR));
/*
* Read in the header and check it */ //fread(pszPtr, 1, HDR_SIZE, f);
if(HDR_SIZE > uSize) { CloseHandle(hFile); uRv = SF_ERR_FILE_FORMAT; goto OSFexit; } if (ReadFile(hFile, pszPtr, HDR_SIZE * sizeof(TCHAR), &dw, 0) == FALSE) { CloseHandle(hFile); uRv = SF_ERR_FILE_ACCESS; goto OSFexit; }
if (memcmp(pszPtr, pszHdr, 10 * sizeof(TCHAR)) != 0) { CloseHandle(hFile); uRv = SF_ERR_FILE_FORMAT; goto OSFexit; }
pszPtr += HDR_SIZE; asSessionFiles[uNdx].dwDataUsed += HDR_SIZE;
/*
* Initialize the index */ asSessionFiles[uNdx].uItemCount = 0; asSessionFiles[uNdx].uItemsAlloc = 64; uSize1 = sizeof(stDSII) * 64; asSessionFiles[uNdx].hIndex = (pstDSII)malloc(uSize1);
if (asSessionFiles[uNdx].hIndex == (pstDSII)0) { CloseHandle(hFile); uRv = SF_ERR_MEMORY_ERROR; goto OSFexit; }
/*
* Read in the data items and add them to to structure * The file is in the format: * * USHORT index * DWORD dwSize * CHAR * size */
pD = &asSessionFiles[uNdx];
pI = pD->hIndex;
nOrderOK = TRUE; sOldID = 0;
for (;;) { sID = 0; dwSZ = -1;
if (ReadFile(hFile, &sID, sizeof(SHORT), &dw, 0) == FALSE) { CloseHandle(hFile); uRv = SF_ERR_FILE_ACCESS; goto OSFexit; } if (ReadFile(hFile, &dwSZ, sizeof(DWORD), &dw, 0) == FALSE) { CloseHandle(hFile); uRv = SF_ERR_FILE_ACCESS; goto OSFexit; }
if ((sID == 0) && (dwSZ == -1)) break;
if ((sID == 0) && (dwSZ == 0)) continue;
if (sOldID > sID) { nOrderOK = FALSE; pI = (pstDSII)0; pszStr = NULL; }
sOldID = sID; /* For next time around */
#if defined(DEBUG_OUTPUT)
wsprintf(acBuffer, "r %c %d(0x%x) %d\r\n", nOrderOK ? 'a' : 'i', sID, sID, dwSZ); OutputDebugString(acBuffer); #endif
if (nOrderOK) { // Do it inline
if (pD->uItemCount >= pD->uItemsAlloc) { #if defined(DEBUG_OUTPUT)
OutputDebugString("Index expanded\r\n"); #endif
/*
* We need to get a bigger chunk of memory */ if (pD->hIndex == (pstDSII)0) { pD->uItemsAlloc = 64; pD->hIndex = (pstDSII)malloc(sizeof(stDSII) * 64); } else { int newSize = pD->uItemsAlloc * 2; stDSII * pTemphIndex = NULL;
pTemphIndex = (pstDSII) realloc(pD->hIndex, (size_t)newSize * sizeof(stDSII));
if (pTemphIndex == NULL) { uRv = SF_ERR_MEMORY_ERROR; goto OSFexit; } else { pD->uItemsAlloc = newSize; pD->hIndex = pTemphIndex; } } }
if (pD->hData == 0) { pD->hData = (BYTE *)malloc(ROUND_UP(4096)); pD->dwDataSize = ROUND_UP(4096); pD->dwDataUsed = 0; }
/*
* Add the item at the end of the list */ nRv = pD->uItemCount;
pIx = pI; pIx += nRv;
pIx->uIndex = sID; pIx->dwSize = dwSZ; pIx->dwOffset = (DWORD)(pszPtr - pszStr);
pD->uItemCount += 1;
//fread(pszPtr, sSZ, 1, f);
if( (DWORD)dwSZ > uSize ) { CloseHandle(hFile); uRv = SF_ERR_FILE_FORMAT; goto OSFexit; } if (ReadFile(hFile, pszPtr, (DWORD)dwSZ, &dw, 0) == FALSE) { CloseHandle(hFile); uRv = SF_ERR_FILE_ACCESS; goto OSFexit; }
pszPtr += dwSZ; asSessionFiles[uNdx].dwDataUsed += dwSZ; } else { TCHAR acBuffer[FNAME_LEN];
//fread(acBuffer, dwSZ, 1, f);
if( (DWORD)dwSZ > sizeof(acBuffer) ) { CloseHandle(hFile); uRv = SF_ERR_FILE_FORMAT; goto OSFexit; }
if (ReadFile(hFile, acBuffer, (DWORD)dwSZ, &dw, 0) == FALSE) { CloseHandle(hFile); uRv = SF_ERR_FILE_ACCESS; goto OSFexit; } sfPutSessionItem(uNdx + 1, (unsigned int)sID, (unsigned long)dwSZ, acBuffer); }
}
/*
* Free things up */
CloseHandle(hFile); }
return SF_OK; }
OSFexit: if (uNdx != SESS_FILE_MAX) { /*
* General cleanup */ if (asSessionFiles[uNdx].hFilename) { free(asSessionFiles[uNdx].hFilename); asSessionFiles[uNdx].hFilename = NULL; }
if (asSessionFiles[uNdx].hData) { free(asSessionFiles[uNdx].hData); asSessionFiles[uNdx].hData = NULL; }
if (asSessionFiles[uNdx].hIndex) { free(asSessionFiles[uNdx].hIndex); asSessionFiles[uNdx].hIndex = NULL; }
memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP)); }
return uRv; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfFlushSessionFile * * DESCRIPTION: * This function is called to write all of the data in a session file out to * disk and release any and all memory associated with the session file handle. * It will not do anything if the session file does not have a file name * associated with it. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * * RETURNS: * ZERO if the file is written, an error code < 0 if there is and error. */ int sfFlushSessionFile(const SF_HANDLE sF) { int nRv = 0; int uNdx = sF - 1; int x; USHORT usIndex; TCHAR *pszName; TCHAR *pszPtr; pstDSII pI; HANDLE hFile; DWORD dw;
if (uNdx >= SESS_FILE_MAX) { nRv = SF_ERR_BAD_PARAMETER; goto CSFexit; }
if (asSessionFiles[uNdx].uBusy == 0) { nRv = SF_ERR_BAD_PARAMETER; goto CSFexit; }
if (asSessionFiles[uNdx].fOpen == 0) { nRv = SF_ERR_FILE_ACCESS; goto CSFexit; }
if (asSessionFiles[uNdx].uChanged != 0) { if (asSessionFiles[uNdx].hFilename == NULL) { nRv = SF_ERR_FILE_ACCESS; goto CSFexit; }
pszName = asSessionFiles[uNdx].hFilename;
/* TODO: put in code to create directorys as necessary */
//f = fopen(pszName, "wb");
hFile = CreateFile(pszName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) { nRv = SF_ERR_FILE_ACCESS; goto CSFexit; }
pszPtr = (TCHAR *)asSessionFiles[uNdx].hData;
/*
* Write out the header first */ if (StrCharGetStrLength(pszPtr) == 0) { /*
* Write out an empty header */ WriteFile(hFile, pszHdr, HDR_SIZE * sizeof(TCHAR), &dw, 0); } else { /*
* Write out the current header */ WriteFile(hFile, pszPtr, HDR_SIZE * sizeof(TCHAR), &dw, 0); }
pszPtr += HDR_SIZE;
pI = asSessionFiles[uNdx].hIndex;
/*
* We loop thru the index and write out all of the stuff */ for (x = 0; x < asSessionFiles[uNdx].uItemCount; x += 1) { if (pI->dwSize != 0) { #if defined(DEBUG_OUTPUT)
unsigned char acBuffer[64];
wsprintf(acBuffer, "w %d(0x%x) %d\r\n", pI->uIndex, pI->uIndex, pI->dwSize); OutputDebugString(acBuffer); #endif
usIndex = (USHORT)pI->uIndex; WriteFile(hFile, &usIndex, sizeof(USHORT), &dw, 0); WriteFile(hFile, &pI->dwSize, sizeof(DWORD), &dw, 0);
WriteFile(hFile, pszPtr, (size_t)pI->dwSize * sizeof(TCHAR), &dw, 0);
pszPtr += pI->dwSize; } pI += 1; }
CloseHandle(hFile); asSessionFiles[uNdx].uChanged = 0;
// Finally, notify the shell so it can update the icon.
//
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH, asSessionFiles[uNdx].hFilename, 0); }
CSFexit:
return nRv; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfReleaseSessionFile * * DESCRIPTION: * This function is called to release any and all memory associated with the * session file handle. This function by itself DOES NOT write any data out * to the file. That must be done elsewhere. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * * RETURNS: * ZERO if everything is OK, otherwise an error code < 0. */ int sfReleaseSessionFile(const SF_HANDLE sF) { unsigned int uNdx = (unsigned int)sF - 1;
if (uNdx > SESS_FILE_MAX) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].uBusy == 0) return SF_ERR_BAD_PARAMETER;
asSessionFiles[uNdx].uBusy = 0;
if (asSessionFiles[uNdx].hFilename) { free(asSessionFiles[uNdx].hFilename); asSessionFiles[uNdx].hFilename = NULL; }
if (asSessionFiles[uNdx].hData) { free(asSessionFiles[uNdx].hData); asSessionFiles[uNdx].hData = NULL; }
if (asSessionFiles[uNdx].hIndex) { free(asSessionFiles[uNdx].hIndex); asSessionFiles[uNdx].hIndex = NULL; }
memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP)); return 0; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfCloseSessionFile * * DESCRIPTION: * This function is called to release any and all memory associated with the * session file handle. This function by itself DOES NOT write any data out * to the file. That must be done elsewhere. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * * RETURNS: * ZERO if everything is OK, otherwise an error code < 0. */ int sfCloseSessionFile(const SF_HANDLE sF) { int rV1, rV2;
rV1 = sfFlushSessionFile(sF); rV2 = sfReleaseSessionFile(sF);
if (rV1 != 0) return rV1;
return rV2; } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfGetSessionFileName * * DESCRIPTION: * This function is called to return the file name currently associated with * the session file handle. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * INT nSize -- the size of the following buffer * PCHAR pszName -- the address of the buffer to copy the name to * * RETURNS: * ZERO if everything is OK, otherwise an error code < 0; */ int sfGetSessionFileName(const SF_HANDLE sF, const int nSize, TCHAR *pszName) { int uNdx = sF - 1; #if DEADWOOD
TCHAR *pszStr = NULL; int len; #endif
if (uNdx > SESS_FILE_MAX) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].uBusy == 0) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].hFilename == NULL) return SF_ERR_BAD_PARAMETER;
//
// Use StrCharCopyN() to copy the filename into the buffer passed.
// This will localize our revisions to the string manipulation
// functions if needed at a later date. REV: 03/01/2001
//
#if DEADWOOD
pszStr = asSessionFiles[uNdx].hFilename;
//strncpy(pszName, pszStr, nSize);
// JYF 03-Dec-1998 we don't want to read more than strlen
// of pszStr and nSize so not to read from inaccessible
// memory when running with debug heap.
len = min (nSize, lstrlen (pszStr)+1); MemCopy(pszName, pszStr, (size_t)len * sizeof(TCHAR)); pszName[nSize-1] = TEXT('\0'); #else
StrCharCopyN(pszName, asSessionFiles[uNdx].hFilename, nSize); #endif
return SF_OK; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfSetSessionFileName * * DESCRIPTION: * This function is called to change the name currently associated with the * session file handle. It does not cause the session file handle to reload * any data or access the disk at all. Data files are read when the session * file is opened and written when the session file is closed. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * PCHAR pszName -- the address of the new file name * * RETURNS: * ZERO if everything is OK, otherwise and error code < 0; */ int sfSetSessionFileName(const SF_HANDLE sF, const TCHAR *pszName) { unsigned int uNdx = (unsigned int)sF - 1; TCHAR *pszStr = NULL;
if (uNdx > SESS_FILE_MAX) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].uBusy == 0) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].fOpen == 0) return SF_ERR_FILE_ACCESS;
if (asSessionFiles[uNdx].hFilename == NULL) { asSessionFiles[uNdx].hFilename = (TCHAR *)malloc(FNAME_LEN * sizeof(TCHAR));
if (asSessionFiles[uNdx].hFilename == NULL) return SF_ERR_MEMORY_ERROR; }
pszStr = asSessionFiles[uNdx].hFilename;
TCHAR_Fill(pszStr, TEXT('\0'), FNAME_LEN); StrCharCopyN(pszStr, (LPTSTR)pszName, FNAME_LEN); pszStr = NULL;
asSessionFiles[uNdx].uChanged = 1; return 0; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfGetSessionItem * * DESCRIPTION: * This function is called to get data from the session file handle. It can * also be used to get the size of a data item. * * If the last arguement, pvData, is NULL, then the size of the item is * returned in *pulSize. If pvData is not NULL, up to *pulSize bytes are * returned at pvData. If the number of bytes returned is less than *pulData, * the new size is set in *pulSize. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * uId -- ID if the item * pulSize -- where the size is found or returned * pvData -- where the data is to be placed * * RETURNS: * ZERO if everything is OK, otherwise and error code < 0; */ int sfGetSessionItem(const SF_HANDLE sF, const unsigned int uId, unsigned long *pulSize, void *pvData) { int lReturn = SF_ERR_BAD_PARAMETER; int uNdx = sF - 1; int dwMinSize; int low; int mid; int high; pstDSII pI; pstDSII pIx; BYTE * pszData;
if (uNdx > SESS_FILE_MAX) { lReturn = SF_ERR_BAD_PARAMETER; } else if (uNdx < 0) { lReturn = SF_ERR_BAD_PARAMETER; } else if (asSessionFiles[uNdx].uBusy == 0) { lReturn = SF_ERR_BAD_PARAMETER; } else if (asSessionFiles[uNdx].fOpen == 0) { lReturn = SF_ERR_FILE_ACCESS; } else if (asSessionFiles[uNdx].uItemCount == 0) { lReturn = SF_ERR_BAD_PARAMETER; } else if ((uId < 1) || (uId > 0x7FFF)) { lReturn = SF_ERR_BAD_PARAMETER; } /*
* See if the item is in the index */ else if (asSessionFiles[uNdx].hIndex == (pstDSII)0) { lReturn = SF_ERR_BAD_PARAMETER; } else { pI = asSessionFiles[uNdx].hIndex;
low = 0; high = asSessionFiles[uNdx].uItemCount - 1;
while (low <= high) { mid = (low + high) / 2; pIx = pI + mid;
if ((int)uId < pIx->uIndex) { high = mid - 1; } else if ((int)uId > pIx->uIndex) { low = mid + 1; } else { /*
* Found the item, see what they want to know */ if (pvData == NULL) { *pulSize = (unsigned long)pIx->dwSize; } else { pszData = asSessionFiles[uNdx].hData; dwMinSize = (int)*pulSize;
if (dwMinSize > pIx->dwSize) { dwMinSize = pIx->dwSize; }
if (dwMinSize) { MemCopy(pvData, pszData + pIx->dwOffset, (size_t)dwMinSize); } }
lReturn = SF_OK; break; } } }
return lReturn; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfCompareSessionItem * * DESCRIPTION: * This function is called to check and see if an item exists in the data * and if it is the same as the passed in item. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * uId -- the ID of the item * ulSize -- the size of the item * pvData -- address of the data * * RETURNS: * TRUE if the two items are the same, otherwise false. */ int sfCompareSessionItem(const SF_HANDLE sF, const unsigned int uId, const unsigned long ulSize, const void *pvData) { int uNdx = sF - 1; int low, mid, high; pstDSII pI; pstDSII pIx; BYTE *pszData;
/*
* See if the item is in the index */ if (asSessionFiles[uNdx].hIndex == (pstDSII)0) return FALSE;
pI = asSessionFiles[uNdx].hIndex;
low = 0; high = asSessionFiles[uNdx].uItemCount - 1;
while (low <= high) { mid = (low + high) / 2; pIx = pI + mid;
if ((int)uId < pIx->uIndex) high = mid - 1;
else if ((int)uId > pIx->uIndex) low = mid + 1;
else { /*
* Check and see if the sizes are the same */ if (ulSize != (unsigned long)pIx->dwSize) return FALSE;
/*
* Check and see if the data is the same */ pszData = asSessionFiles[uNdx].hData + pIx->dwOffset;
if (memcmp((BYTE *)pvData, pszData, ulSize) == 0) return TRUE; return FALSE; } } return FALSE; }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION: sfPutSessionItem * * DESCRIPTION: * This function is called to add or modify an entry in the session file data * associated with the current session file handle. It does not cause the * actual session file itself to be written. That is done only when the * session file handle is closed. * * ARGUEMENTS: * SF_HANDLE sF -- the session file handle * uId -- the ID of the item * ulSize -- the size of the item * pvData -- address of the data * * RETURNS: * ZERO if everything is OK, otherwise and error code < 0; */ int sfPutSessionItem(const SF_HANDLE sF, const unsigned int uId, const unsigned long ulSize, const void *pvData) { int uNdx = sF - 1; int x, y; int32 dwSlide; int32 dwOffset; int32 dwNewSize; pstDSII pI; pstDSII pIx, pIy; BYTE *pszData;
#if defined(DEBUG_OUTPUT)
unsigned char acBuffer[80]; #endif
if (uNdx > SESS_FILE_MAX) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].uBusy == 0) return SF_ERR_BAD_PARAMETER;
if (asSessionFiles[uNdx].fOpen == 0) return SF_ERR_FILE_ACCESS;
if ((uId < 1) || (uId > 0x7FFF)) return SF_ERR_BAD_PARAMETER;
if (sfCompareSessionItem(sF, uId, ulSize, pvData)) return SF_OK;
x = sfAddToIndex(uNdx, (unsigned short)uId, 0, 0);
pI = asSessionFiles[uNdx].hIndex;
if (x != (-1)) { pIx = pI + x; if (pIx->dwSize == 0) { /*
* Its a new item */ dwSlide = (int32)ulSize; if (x == 0) dwOffset = HDR_SIZE; else dwOffset = (pI+x-1)->dwOffset + (pI+x-1)->dwSize;
#if defined(DEBUG_OUTPUT)
wsprintf(acBuffer, "New 0x%x slide %d offset 0x%x", uId, dwSlide, dwOffset); OutputDebugString(acBuffer); #endif
} else { /*
* Its a replacement item */ dwSlide = (int)ulSize - (int)pIx->dwSize; dwOffset = pIx->dwOffset;
#if defined(DEBUG_OUTPUT)
wsprintf(acBuffer, "Rep 0x%x slide %d offset 0x%x", uId, dwSlide, dwOffset); OutputDebugString(acBuffer); #endif
}
/*
* Check the memory requirements */ dwNewSize = asSessionFiles[uNdx].dwDataUsed + dwSlide;
if (dwNewSize > asSessionFiles[uNdx].dwDataSize) { /*
* Need to allocate a new chunk of memory */ BYTE *hG =(BYTE *) realloc(asSessionFiles[uNdx].hData, ROUND_UP(dwNewSize));
if (hG == NULL) { return SF_ERR_MEMORY_ERROR; } else { asSessionFiles[uNdx].hData = hG; asSessionFiles[uNdx].dwDataSize = ROUND_UP(dwNewSize); } }
/*
* Move the old data to the point necessary */ pszData = asSessionFiles[uNdx].hData; asSessionFiles[uNdx].dwDataUsed = dwNewSize;
if (dwSlide < 0) { /* shrink the current space */ dwNewSize = asSessionFiles[uNdx].dwDataSize; dwNewSize -= dwOffset; dwNewSize += dwSlide;
memmove(pszData + dwOffset, /* destination */ pszData + dwOffset - dwSlide, /* source */ (size_t)(dwNewSize - 1)); /* count */
#if defined(DEBUG_OUTPUT)
wsprintf(acBuffer, " shrink from 0x%lx to 0x%lx size 0x%x\r\n", (long)(pszData + dwOffset - dwSlide), (long)(pszData + dwOffset), dwNewSize -1); OutputDebugString(acBuffer); #endif
} else { /* expand the current space */ dwNewSize = asSessionFiles[uNdx].dwDataSize; dwNewSize -= dwOffset; dwNewSize -= dwSlide;
memmove(pszData + dwOffset + dwSlide, /* destination */ pszData + dwOffset, /* source */ (size_t)(dwNewSize - 1)); /* count */
#if defined(DEBUG_OUTPUT)
wsprintf(acBuffer, " expand from 0x%lx to 0x%lx size 0x%x\r\n", (long)(pszData + dwOffset), (long)(pszData + dwOffset + dwSlide), dwNewSize - 1); OutputDebugString(acBuffer); #endif
}
/*
* Copy in the new data */ memmove(pszData + dwOffset, /* destination */ pvData, /* source */ (unsigned int)ulSize); /* count */
/*
* Update the item in the index for the current item */ pIx->dwSize = (int32)ulSize; pIx->dwOffset = dwOffset;
/*
* Adjust all the following items in the index */ for (y = x + 1; y < (int)asSessionFiles[uNdx].uItemCount; y += 1) { pIy = pI + y; pIy->dwOffset += dwSlide; }
asSessionFiles[uNdx].uChanged = 1; return 0; }
return SF_ERR_BAD_PARAMETER; }
|