home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
smart21b.zip
/
SAMPLES
/
OS21321
/
LINKXR.C
< prev
Wrap
C/C++ Source or Header
|
1992-10-20
|
35KB
|
1,039 lines
/*************************************************************
LINKXR.c
**************************************************************/
#include "link.h"
/************ External GLOBALS *******************************/
extern CHAR szFileName[CCHMAXPATH];
extern CHAR szXRName[MAXXRNAME+1];
extern USHORT usRetXRType;
extern BOOL FILE_ISOPEN;
extern BOOL FILE_CHANGED;
extern BOOL COMMAND_LINE_FILE;
extern HHXRP hhp;
extern CHAR *pAlloc,*szEditBuf,*szAscii,*szScratch;
extern HOLDFXR *pHoldFXR;
extern DELETELIST *pDelList;
extern XRDATA ConvTable[XRTABLESIZE];
/*************************************************************/
/*
* Function name: AddXR()
*
* Parameters: hwnd which is the current window handle.
*
* Returns: TRUE iff the XR is successfully added.
*
* Purpose: This routine handles the addition of a new XR to the linked list.
*
* Usage/Warnings: Routine does NOT do full memory error trapping and the
* insert message to the l-box is not error checked.
*
* Calls: EditXRValue()
*/
BOOL AddXR(HWND hwnd)
{
HOLDFXR *pFXR=pHoldFXR; /* Points to the beginning of the XR list */
HOLDFXR *pNewFXR; /* Used to temporarily hold the new XR */
PASSDATA PData;
if(!FILE_ISOPEN)
return(FALSE);
if(!WinDlgBox(HWND_DESKTOP, /* get new XR name and type */
hwnd,
AddXRProc,
NULL,
IDD_ADDXR,
NULL))
return(FALSE); /* they said cancel */
if (WinDlgBox(HWND_DESKTOP,
hwndFrame, /* handle of the owner */
OpenDlg, /* dialog procedure address */
NULLHANDLE, /* location of dialog resource */
IDD_OPEN, /* resource identifier */
NULL)) { /* application-specific data */
GetMem(pNewFXR, sizeof(HOLDFXR)); /* Allocate space for new XR struct */
pNewFXR->cbName = (CHAR) strlen(szXRName); /* Fill in new structure */
pNewFXR->cbValue= 0;
pNewFXR->fXR = 0; /* Need bit NOT set */
GetMem(pNewFXR->szName,pNewFXR->cbName+1); /* Name returned in szXRName */
strcpy(pNewFXR->szName,strupr(szXRName));
pNewFXR->aValue = NULL;
pNewFXR->next = NULL;
if(pHoldFXR == NULL) /* It's the first XR for the file */
{
pHoldFXR = pNewFXR;
}
else /* Add XR to the end of the linked list */
{
while(pFXR->next)
pFXR = pFXR->next;
pFXR->next = pNewFXR;
}
PData.Point = (CHAR *) pNewFXR; /* Setup user data for call */
PData.cbMulti = 0; /* to edit of the name and */
PData.usMultiOffset = 0; /* XR Value */
if(!EditXRValue(hwnd,&PData)) /* They canceled the edit */
{
if(pFXR) /* It's not the only XR */
pFXR->next = NULL; /* Disconnect the partial new XR */
else
pHoldFXR = NULL; /* The new XR was the first one */
FreeMem(pNewFXR->szName,pNewFXR->cbName+1);
FreeMem(pNewFXR,sizeof(HOLDFXR));
return(FALSE);
}
WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_INSERTITEM, /* Insert name in L-Box */
MPFROM2SHORT(LIT_END,0),
MPFROMP(pNewFXR->szName));
return(TRUE);
}
/*
* Calls: Free_FXRList(), CheckXRIntegrity()
*/
BOOL QueryXRs(HWND hwnd,CHAR *pszPath)
{
CHAR *pAlloc; /* Holds the FXR struct returned by DosEnumAttribute */
/* also used to create the GXRLIST for DosQPathInfo */
CHAR *pBigAlloc; /* Temp buffer to hold each XR as it is read in */
USHORT cbBigAlloc; /* Size of buffer */
ULONG ulEntryNum = 1; /* count of current XR to read (1-relative) */
ULONG ulEnumCnt; /* Number of XRs for Enum to return, always 1 */
HOLDFXR *pLastIn; /* Points to last XR added, so new XR can link */
HOLDFXR *pNewFXR; /* Struct to build the new XR in */
FXR *pFXR; /* Used to read from Enum's return buffer */
GXRLIST *pGXRList; /* Ptr used to set up buffer for DosQPathInfo call */
XROP eaopGet; /* Used to call DosQPathInfo */
GetMem(pAlloc,MAX_GXR); /* Allocate enough room for any GXR List */
pFXR = (FXR *) pAlloc; /* pFXR always uses pAlloc buffer */
pHoldFXR = NULL; /* Reset the pointer for the XR linked list */
while(TRUE) /* Loop continues until there are no more XRs */
{
ulEnumCnt = 1; /* Only want to get one XR at a time */
if(DosEnumAttribute(Ref_ASCIIZ, /* Read into pAlloc Buffer */
pszPath, /* Note that this does not */
ulEntryNum, /* get the aValue field, */
pAlloc, /* so DosQPathInfo must be */
MAX_GXR, /* called to get it. */
&ulEnumCnt,
(LONG) GetInfoLevel1,
0L))
break; /* There was some sort of error */
if(ulEnumCnt != 1) /* All the XRs have been read */
break;
ulEntryNum++;
GetMem(pNewFXR,sizeof(HOLDFXR));
if (pNewFXR == NULL) /* Out of memory */
{
FreeMem(pAlloc,MAX_GXR);
Free_FXRList(pHoldFXR,pDelList);
return (FALSE);
}
pNewFXR->cbName = pFXR->cbName; /* Fill in the HoldFXR structure */
pNewFXR->cbValue= pFXR->cbValue;
pNewFXR->fXR = pFXR->fXR;
pNewFXR->next = NULL;
GetMem(pNewFXR->szName,pFXR->cbName +1); /* Allocate for 2 arrays */
GetMem(pNewFXR->aValue,pFXR->cbValue);
if (!pNewFXR->szName || !pNewFXR->aValue) /* Out of memory */
{
if(pNewFXR->szName)
FreeMem(pNewFXR->szName,pFXR->cbName+1);
if(pNewFXR->aValue)
FreeMem(pNewFXR->aValue,pFXR->cbValue);
FreeMem(pAlloc, MAX_GXR);
FreeMem(pNewFXR,sizeof(HOLDFXR));
Free_FXRList(pHoldFXR,pDelList);
return (FALSE);
}
strcpy(pNewFXR->szName,pAlloc+sizeof(FXR)); /* Copy in XR Name */
cbBigAlloc = sizeof(FXRLIST) + pNewFXR->cbName+1 + pNewFXR->cbValue;
GetMem(pBigAlloc,cbBigAlloc);
if (pBigAlloc == NULL)
{
FreeMem(pNewFXR->szName,pFXR->cbName+1);
FreeMem(pNewFXR->aValue,pFXR->cbValue);
FreeMem(pAlloc, MAX_GXR);
FreeMem(pNewFXR,sizeof(HOLDFXR));
Free_FXRList(pHoldFXR,pDelList);
return (FALSE);
}
pGXRList = (GXRLIST *) pAlloc; /* Set up GXRList structure */
pGXRList->cbList = sizeof(GXRLIST) + pNewFXR->cbName; /* +1 for NULL */
pGXRList->list[0].cbName = pNewFXR->cbName;
strcpy(pGXRList->list[0].szName,pNewFXR->szName);
eaopGet.fpGXRList = (GXRLIST far *) pAlloc;
eaopGet.fpFXRList = (FXRLIST far *) pBigAlloc;
eaopGet.fpFXRList->cbList = cbBigAlloc;
DosQPathInfo(pszPath, /* Get the complete XR info */
GetInfoLevel3,
(PVOID) &eaopGet,
sizeof(XROP),
0L);
memcpy(pNewFXR->aValue, /* Copy the value to HoldFXR */
pBigAlloc+sizeof(FXRLIST)+pNewFXR->cbName+1,
pNewFXR->cbValue);
FreeMem(pBigAlloc,cbBigAlloc); /* Release the temp Enum buffer */
if(!CheckXRIntegrity(pNewFXR->aValue,pNewFXR->cbValue)) /* Bad XR */
{
FreeMem(pNewFXR->szName,pFXR->cbName+1);
FreeMem(pNewFXR->aValue,pFXR->cbValue);
FreeMem(pNewFXR,sizeof(HOLDFXR));
continue; /* Don't add this XR to linked list */
}
if(pHoldFXR == NULL) /* If first XR, set pHoldFXR */
pHoldFXR = pNewFXR;
else /* Otherwise, add to end of list */
pLastIn->next = pNewFXR;
pLastIn = pNewFXR; /* Update the end of the list */
}
FreeMem(pAlloc, MAX_GXR); /* Free up the GXR buf for DosEnum */
return (TRUE);
}
/*
* Function name: CheckXRIntegrity()
*
* Calls: MultiTypeIndex()
*/
BOOL CheckXRIntegrity(CHAR *aBuf,USHORT cbBuf)
{
USHORT *pusPtr = (USHORT *) aBuf;
USHORT usOffset;
CHAR *aEndPtr;
usOffset = LookupXRType(*pusPtr); /* Get the XR type */
switch(ConvTable[usOffset].usFldType)
{
case IDD_LPDATA:
pusPtr++;
if(*pusPtr + 2*sizeof(USHORT) == cbBuf)
return TRUE;
else
return FALSE;
case IDD_MULTILIST:
if(*pusPtr == XR_MVMT)
{
pusPtr += 2;
/* This checks where the end of the m-m list ends to determine
the size of the XR. This is probably not good if the XR is
badly corrupted and it points to protected memory */
aEndPtr = MultiTypeIndex(aBuf,*pusPtr);
if(aEndPtr - aBuf == cbBuf)
return TRUE;
else
return FALSE;
}
else /* Single type, multi-value is not yet implemented */
{
return TRUE;
}
default:
return FALSE;
}
return TRUE;
}
/*
* Function name: Free_FXRList()
*
*/
VOID Free_FXRList(HOLDFXR *pFXR,DELETELIST *pDList)
{
HOLDFXR *next; /* Holds the next field since we free the structure */
/* before reading the current next field */
DELETELIST *Dnext; /* Same purpose as *next */
while(pFXR)
{
next = pFXR->next;
if(pFXR->szName) /* Free if non-NULL name */
FreeMem(pFXR->szName,pFXR->cbName+1);
if(pFXR->aValue) /* Free if non-NULL value */
FreeMem(pFXR->aValue,pFXR->cbValue);
FreeMem(pFXR,sizeof(HOLDFXR)); /* Free HoldFXR struct */
pFXR = next;
}
while(pDList)
{
Dnext = pDList->next;
if(pDList->XRName)
FreeMem(pDList->XRName,strlen(pDList->XRName)+1);
FreeMem(pDList,sizeof(DELETELIST));
pDList = Dnext;
}
}
/*
* Function name: LookupXRType()
*
* Calls:
*/
USHORT LookupXRType(USHORT usType)
{
USHORT cnt;
for(cnt=0;cnt<XRTABLESIZE-1;cnt++)
if(ConvTable[cnt].usPrefix == usType)
return(cnt);
return(cnt);
}
/*
* Function name: DeleteCurXR()
*
* Calls: GetCurFXR()
*/
VOID DeleteCurXR(HWND hwnd)
{
HOLDFXR *pFXR,*pFXRPrev;
DELETELIST *pDL,*pDLcnt; /* Utility ptrs for manipulating the Del list */
LONG lOffset;
pFXR = GetCurFXR(hwnd,pHoldFXR); /* Gets a pointer to item to delete */
if (pFXR == NULL)
return;
/* These two allocations should be checked for out of memory */
GetMem(pDL,sizeof(DELETELIST)); /* Add Name to Delete List */
GetMem(pDL->XRName,pFXR->cbName+1);
strcpy(pDL->XRName,pFXR->szName);
pDL->next = NULL;
if(pDelList == NULL) /* The del list was previously empty */
pDelList = pDL;
else /* tack name onto the end of the list */
{
pDLcnt = pDelList;
while(pDLcnt->next)
pDLcnt = pDLcnt->next;
pDLcnt->next = pDL;
}
lOffset = (LONG) WinSendDlgItemMsg(hwnd, IDD_LBOX,
LM_QUERYSELECTION,0,0);
WinSendDlgItemMsg(hwnd, IDD_LBOX,
LM_DELETEITEM,MPFROMSHORT((SHORT) lOffset),0L);
if(lOffset<1) /* Remove pFXR from the linked list */
{
pHoldFXR = pFXR->next;
}
else
{
pFXRPrev = pHoldFXR;
while(--lOffset) /* Find previous XR */
pFXRPrev = pFXRPrev->next;
pFXRPrev->next = pFXR->next;
}
FreeMem(pFXR->szName,pFXR->cbName+1); /* Release the memory */
FreeMem(pFXR->aValue,pFXR->cbValue);
FreeMem(pFXR,sizeof(HOLDFXR));
FILE_CHANGED = TRUE;
}
/*
* Function name: CurXRType()
*
*/
USHORT CurXRType(HOLDFXR *pFXR) /* Same as GetUSHORT(,0); */
{
USHORT *pusType; /* XR Type is stored in first USHORT of aValue field */
pusType = (USHORT *) pFXR->aValue;
return(*pusType);
}
/*
* Function name: GetUSHORT()
*/
USHORT GetUSHORT(HOLDFXR *pFXR,USHORT index)
{
USHORT *pusType;
pusType = (USHORT *) pFXR->aValue;
while(index-- > 0)
pusType++;
return(*pusType);
}
/*
* Function name: WriteXRs()
*/
VOID WriteXRs(HWND hwnd)
{
DELETELIST *pDL = pDelList,*pDLnext;
HOLDFXR *pHFXR= pHoldFXR;
XROP eaopWrite;
CHAR aBuf[MAX_GXR],*aPtr;
FXR *pFXR = (FXR *) &aBuf[sizeof(ULONG)];
USHORT usRet,usMemNeeded;
ULONG *pulPtr=(ULONG *) aBuf; /* Initally points to top of FXRLIST */
if(!FILE_ISOPEN || !FILE_CHANGED) /* Don't write unless it's necessary */
return;
eaopWrite.fpFXRList = (FXRLIST far *) aBuf; /* Setup fields that won't */
pFXR->fXR = 0; /* change for the delete */
pFXR->cbValue = 0; /* calls to DosSetPathInfo */
while(pDL) /* Clean out all the deleted XR names */
{
pFXR->cbName = (UCHAR) strlen(pDL->XRName);
*pulPtr = sizeof(FXRLIST) + pFXR->cbName+1; /* +1 for NULL */
strcpy(aBuf+sizeof(FXRLIST),pDL->XRName);
usRet=DosSetPathInfo(szFileName, /* Delete XR's by saying cbValue=0 */
SetInfoLevel2,
(PVOID) &eaopWrite,
(USHORT) sizeof(XROP),
DSPI_WRTTHRU,
0L);
pDLnext = pDL->next; /* Temp hold next pDL */
FreeMem(pDL->XRName, pFXR->cbName+1); /* Free up current Del struct */
FreeMem(pDL, sizeof(DELETELIST));
pDL = pDLnext; /* Set pDL to saved value */
}
pDelList = NULL; /* DelList is now empty */
while(pHFXR) /* Go through each HoldFXR */
{
usMemNeeded = sizeof(FXRLIST) + pHFXR->cbName+1 + pHFXR->cbValue;
GetMem(aPtr,usMemNeeded);
eaopWrite.fpFXRList = (FXRLIST far *) aPtr; /* Fill in eaop struct */
eaopWrite.fpFXRList->cbList = usMemNeeded;
eaopWrite.fpFXRList->list[0].fXR = pHFXR->fXR;
eaopWrite.fpFXRList->list[0].cbName = pHFXR->cbName;
eaopWrite.fpFXRList->list[0].cbValue = pHFXR->cbValue;
strcpy(aPtr + sizeof(FXRLIST), pHFXR->szName);
memcpy(aPtr + sizeof(FXRLIST) + pHFXR->cbName+1,
pHFXR->aValue, pHFXR->cbValue);
usRet=DosSetPathInfo(szFileName, /* Write out the XR */
SetInfoLevel2,
(PVOID) &eaopWrite,
(USHORT) sizeof(XROP),
DSPI_WRTTHRU,0L);
FreeMem(aPtr,usMemNeeded); /* Free up the FXRLIST struct */
pHFXR = pHFXR->next;
}
FILE_CHANGED = FALSE;
}
/*
* Function name: EditXRValue()
*
*/
BOOL EditXRValue(HWND hwnd, PASSDATA *pPDat)
{
USHORT usXRType; /* Holds the field type to be edited */
USHORT *pusPtr;
USHORT usSize; /* Holds the delta difference of the old and new buffers */
CHAR *szNew,*szTrash; /* Temporary pointers */
PASSDATA PDat;
HOLDFXR *pFXR = (HOLDFXR *) pPDat->Point; /* The XR to be edited */
/* Determine the type of XR that will be edited */
if(pPDat->cbMulti) /* It's a multi-type job */
{
pusPtr = (USHORT *) MultiTypeIndex(pFXR->aValue+pPDat->usMultiOffset,
pPDat->usIndex);
usXRType = *pusPtr;
}
else if(pFXR->cbValue) /* It isn't a new XR name */
{
pusPtr = (USHORT *) pFXR->aValue;
usXRType = *pusPtr;
}
else /* It's a new XR */
{
usXRType = ConvTable[usRetXRType].usPrefix;
}
PDat.Point = pFXR->szName; /* General setup for AsciiEditProc */
PDat.usIndex = pPDat->cbMulti ? 1 : 0; /* =1 if there is a multi */
PDat.fFlag = (BYTE) ((pFXR->fXR & 0x80) ? TRUE : FALSE);
switch(usXRType)
{
case XR_ASCIIZ:
case XR_ASCIIZFN:
case XR_ASCIIZXR:
case XR_ASN1:
if(pPDat->cbMulti) /* It is a multi-type field */
szAscii=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex)
+sizeof(USHORT);
else if(pFXR->cbValue) /* There is a current value */
szAscii=pFXR->aValue+sizeof(USHORT);
else /* It's a new XR */
szAscii=NULL;
if(!WinDlgBox(HWND_DESKTOP, /* Do an ascii text edit */
hwnd,
AsciiEditProc,
NULL,
IDD_ASCIIEDIT,
&PDat))
return(FALSE); /* They said cancel */
if(PDat.fFlag) /* Handle the need/nice bit */
PDat.fFlag = 0x80;
if(PDat.fFlag != (PDat.fFlag & 0x80))
FILE_CHANGED = TRUE;
pFXR->fXR = (pFXR->fXR & 0x7f) | PDat.fFlag;
if(stricmp(strupr(szXRName),pFXR->szName)) /* The name changed */
ChangeName(hwnd,pFXR,szXRName);
if(pFXR->cbValue) /* There is a current value */
{
if(!strcmp(szAscii,szScratch)) /* It hasn't changed */
return(TRUE);
if(pPDat->cbMulti) /* Do the whole thing here if m-m */
{
usSize = strlen(szScratch)-strlen(szAscii); /* Change in size */
if(usSize > 0) /* The new string is longer */
{
ResizeMem(pFXR->aValue, /* Enlarge the XR size */
pFXR->cbValue,
pFXR->cbValue+usSize);
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex+1);
memmove(szTrash+usSize, /* Move end of XR to make room */
szTrash,
pFXR->cbValue-(szTrash-pFXR->aValue));
}
else if(usSize < 0) /* The new string is shorter */
{
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex+1);
memmove(szTrash+usSize, /* Move back the end of the XR */
szTrash,
pFXR->cbValue-(szTrash-pFXR->aValue));
ResizeMem(pFXR->aValue, /* Shrink the XR buffer */
pFXR->cbValue,
pFXR->cbValue+usSize);
}
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex);
strcpy(szTrash+sizeof(USHORT),szScratch); /* Copy in new val */
pFXR->cbValue+=usSize; /* Change buffer count */
return(FILE_CHANGED = TRUE); /* Done with m-m edit */
}
else
{
FreeMem(pFXR->aValue,pFXR->cbValue); /* Release old Value mem */
}
}
GetMem(szNew,strlen(szScratch)+3); /* +3 for Type & NULL */
pusPtr = (USHORT *) szNew;
*pusPtr= usXRType; /* Set type in new buffer */
strcpy(szNew+2,szScratch); /* Copy in the new value */
pFXR->aValue = szNew; /* Fix up the structure */
pFXR->cbValue= strlen(szScratch)+3;
return(FILE_CHANGED = TRUE);
case XR_LPBINARY:
case XR_LPASCII:
case XR_LPMETAFILE:
if(pPDat->cbMulti) /* It is a multi-type field */
{ /* szTrash points to field to edit, pusPtr to the field length */
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex);
pusPtr = (USHORT *) ((CHAR *) szTrash + sizeof(USHORT));
usSize = *pusPtr;
if(usSize) /* It isn't a new XR */
{
GetMem(szAscii,usSize+1); /* Set up inital value for edit */
memcpy(szAscii,szTrash+2*sizeof(USHORT),usSize);
szAscii[usSize]=NULL;
}
else /* No inital value */
szAscii = NULL;
}
else if(pFXR->cbValue)
{
usSize=GetUSHORT(pFXR,1); /* Get size and set inital value */
if(usSize)
{
GetMem(szTrash,usSize+1); /* +1 for null */
memcpy(szTrash,pFXR->aValue+4,usSize);
szTrash[usSize]=NULL;
szAscii=szTrash;
}
else
szAscii = NULL;
}
else
szAscii = NULL;
if(!WinDlgBox(HWND_DESKTOP, /* Do an ascii text edit */
hwnd,
AsciiEditProc,
NULL,
IDD_ASCIIEDIT,
&PDat))
{ /* Cancel, but check if memory needs to be freed before exit */
if(pPDat->cbMulti || pFXR->cbValue)
if(szAscii) /* It's not NULL */
FreeMem(szAscii,strlen(szAscii)+1); /* +1 for NULL */
return(FALSE);
}
if(PDat.fFlag) /* Handle the need/nice bit */
PDat.fFlag = 0x80;
if(PDat.fFlag != (PDat.fFlag & 0x80))
FILE_CHANGED = TRUE;
pFXR->fXR = (pFXR->fXR & 0x7f) | PDat.fFlag;
if(stricmp(strupr(szXRName),pFXR->szName)) /* The name changed */
ChangeName(hwnd,pFXR,szXRName);
if(pFXR->cbValue) /* There is a current value */
{
if(!strcmp(szAscii,szScratch)) /* It hasn't changed */
{
if(szAscii)
FreeMem(szAscii,usSize+1);
return(TRUE);
}
if(szAscii) /* Free default value buffer */
FreeMem(szAscii,usSize+1);
if(pPDat->cbMulti) /* Do the whole thing here is multi-type */
{
USHORT usDelta = strlen(szScratch) - usSize; /* Change in len */
if(usDelta > 0) /* The new string is longer, resize first */
{
ResizeMem(pFXR->aValue,pFXR->cbValue,pFXR->cbValue+usDelta);
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex+1);
memmove(szTrash+usDelta,szTrash,
pFXR->cbValue-(szTrash-pFXR->aValue));
}
else if(usDelta < 0) /* move first, resize afterwards */
{
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex+1);
memmove(szTrash+usDelta,szTrash,
pFXR->cbValue-(szTrash-pFXR->aValue));
ResizeMem(pFXR->aValue,pFXR->cbValue,pFXR->cbValue+usDelta);
}
szTrash=MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex);
memmove(szTrash+2*sizeof(USHORT),szScratch,strlen(szScratch));
pusPtr = (USHORT *) ((CHAR *) szTrash + sizeof(USHORT));
*pusPtr= strlen(szScratch); /* Set the length field */
pFXR->cbValue += usDelta; /* Adjust struct len field */
return(FILE_CHANGED = TRUE);
}
FreeMem(pFXR->aValue,pFXR->cbValue); /* Free up old value */
}
GetMem(szNew,strlen(szScratch)+4); /* Get space for new value */
pusPtr = (USHORT *) szNew;
*pusPtr= usXRType; /* Set type field */
pusPtr++;
*pusPtr= strlen(szScratch); /* Set length field */
memcpy(szNew+4,szScratch,*pusPtr); /* Copy in new value */
pFXR->aValue = szNew; /* Adjust pointers */
pFXR->cbValue= strlen(szScratch)+4; /* +4 for type and LP cnt */
return(FILE_CHANGED = TRUE);
case XR_MVMT: /* It's multi-value multi-type */
if(pFXR->cbValue == 0) /* It's a new XR */
{
GetMem(pFXR->aValue,3*sizeof(USHORT)); /* Allocate empty m-m XR */
pFXR->cbValue = 3*sizeof(USHORT);
pusPtr = (USHORT *) pFXR->aValue;
*pusPtr = 0xffdf; /* Multi-value, multi-type */
pusPtr+=2; /* Skip type, codepage */
*pusPtr = 0; /* No fields initially */
FILE_CHANGED = TRUE;
}
/* Set up passed in data */
if(pPDat->cbMulti) /* It's a multi-type job */
{
szNew = MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex);
szTrash = MultiTypeIndex(pFXR->aValue + pPDat->usMultiOffset,
pPDat->usIndex+1);
PDat.usMultiOffset = szNew - pFXR->aValue;
PDat.cbMulti = szTrash - szNew;
}
else
{
PDat.usMultiOffset = 0;
PDat.cbMulti = pFXR->cbValue;
}
PDat.Point = (CHAR *) pFXR;
WinDlgBox(HWND_DESKTOP, /* Do the Multi-type edit */
hwnd,
MultiTypeProc,
NULL,
IDD_MULTIBOX,
&PDat);
return(TRUE);
}
}
/*
* Function name: XRExists()
*
*/
BOOL XRExists(CHAR *szXRName)
{
HOLDFXR *phFXR=pHoldFXR;
while(phFXR)
{
if(!stricmp(szXRName,phFXR->szName))
return(TRUE);
phFXR=phFXR->next;
}
return(FALSE);
}
/*
* Function name: ChangeName()
*
*/
VOID ChangeName(HWND hwnd,HOLDFXR *pFXR,CHAR *szName)
{
CHAR *szTemp;
DELETELIST *pDL;
GetMem(szTemp,strlen(szName+1)); /* Allocate space for new name */
if(!szTemp)
return;
GetMem(pDL,(USHORT) sizeof(DELETELIST)); /* Allocate a new delete struct */
pDL->XRName = pFXR->szName; /* Fill in DeleteList struct */
pDL->next = pDelList;
pDelList = pDL;
strcpy(szTemp,szName); /* Copy name to permanent buffer */
pFXR->szName = szTemp; /* Fix up struct */
pFXR->cbName = (CHAR) strlen(szName);
FILE_CHANGED = TRUE;
}
/*
* Function name: MultiTypeIndex()
*/
CHAR *MultiTypeIndex(CHAR *pMulti, USHORT usIndex)
{
USHORT *pusPtr;
USHORT usOffset;
pMulti += 3*sizeof(USHORT); /* skip over 0xffdf, codepage, and field cnt */
while(usIndex--) /* loop to skip over correct # of flds */
{
pusPtr = (USHORT *) pMulti;
usOffset = LookupXRType(*pusPtr); /* Get offset of field type */
pMulti += sizeof(USHORT); /* Skip over the type field */
switch(ConvTable[usOffset].usFldType)
{
case IDD_ASCIIZ:
while(*pMulti++); /* Increment to point after NULL */
break;
case IDD_LPDATA:
pusPtr = (USHORT *) pMulti; /* Get the length */
pMulti += *pusPtr + sizeof(USHORT); /* skip to end */
break;
case IDD_MULTILIST:
if(*pusPtr == XR_MVMT) /* m-m, do a recursive call to skip fld */
{
pusPtr = (USHORT *) pMulti; /* points to field cnt */
pMulti = MultiTypeIndex(pMulti-sizeof(USHORT),*pusPtr);
break;
}
/* Not yet implemented for Multi-valued single-type stuff... */
break;
}
}
return(pMulti);
}
/*
* Function name: XRValueString()
*/
CHAR *XRValueString(HWND hwnd,CHAR *aXRVal)
{
USHORT *pusPtr= (USHORT *) aXRVal; /* Points to XR Type */
CHAR *szRet,*szTemp; /* szRet points to return string */
switch(*pusPtr)
{
case XR_ASCIIZ: /* For asciiz strings, return MAXSHOWSIZE-1 chars */
case XR_ASCIIZFN:
case XR_ASCIIZXR:
case XR_ASN1:
aXRVal += sizeof(USHORT);
if(strlen(aXRVal)<MAXSHOWSIZE)
{
GetMem(szRet,strlen(aXRVal)+1);
strcpy(szRet,aXRVal);
}
else
{
GetMem(szRet,MAXSHOWSIZE);
strncpy(szRet,aXRVal,MAXSHOWSIZE-4);
strcpy (szRet+MAXSHOWSIZE-4,"...");
szRet[MAXSHOWSIZE-1]=NULL;
}
return(szRet);
case XR_LPASCII: /* Display up to first MAXSHOWSIZE-1 chars */
case XR_LPMETAFILE:
pusPtr++;
aXRVal += 2*sizeof(USHORT);
if(*pusPtr < MAXSHOWSIZE)
{
GetMem(szRet,*pusPtr +1);
strncpy(szRet,aXRVal,*pusPtr);
szRet[*pusPtr]=NULL;
}
else
{
GetMem(szRet,MAXSHOWSIZE);
strncpy(szRet,aXRVal,MAXSHOWSIZE-4);
strcpy (szRet+MAXSHOWSIZE-4,"...");
szRet[MAXSHOWSIZE-1]=NULL;
}
return(szRet);
/* For the rest of the types, just display the field type */
case XR_LPBINARY:
szTemp = "*** LP Binary ***";
break;
case XR_LPBITMAP:
szTemp = "*** LP Bitmap ***";
break;
case XR_LPICON:
szTemp = "*** LP Icon ***";
break;
case XR_MVMT:
szTemp = "*** Multi-value Multi-type ***";
break;
case XR_MVST:
szTemp = "*** Multi-value Single-type ***";
break;
default:
szTemp = "*** Unknown XR type ***";
break;
}
GetMem(szRet,strlen(szTemp)+1); /* Copy string from static to dynamic */
strcpy(szRet,szTemp);
return(szRet);
}
/*
* Function name: MultiAdd()
*/
VOID MultiAdd(HWND hwnd, HOLDFXR *pFXR,PASSDATA FAR *pPDat)
{
USHORT usSize;
USHORT *pusPtr;
CHAR aUtility[6]; /* Used to hold the header for all XR types */
CHAR *pInsert,*pValue;
PASSDATA PDat;
PDat.Point = pFXR->szName;
if(!WinDlgBox(HWND_DESKTOP, /* Get the name and type */
hwnd,
AddXRProc,
NULL,
IDD_ADDXR,
&PDat))
return; /* They said cancel */
pusPtr = (USHORT *) aUtility;
*pusPtr= ConvTable[usRetXRType].usPrefix; /* Set the type in header buf */
switch(ConvTable[usRetXRType].usFldType)
{
case IDD_ASCIIZ: /* make buffer look like: xx FF 00, size 3 */
usSize = 3;
aUtility[2]=0;
break;
case IDD_LPDATA: /* make the buffer look like: xx FF 00 00, size 4 */
usSize = 4;
pusPtr = (USHORT *) &aUtility[2];
*pusPtr= 0;
break;
case IDD_MULTILIST:
usSize = 6;
pusPtr = (USHORT *) &aUtility[2];
*pusPtr= 0; /* Zero out codepage */
pusPtr++;
*pusPtr= 0; /* Zero out fld cnt */
break;
}
/* Increase XR size to accomodate the header */
ResizeMem(pFXR->aValue,pFXR->cbValue,pFXR->cbValue+usSize);
pusPtr = (USHORT *) ((CHAR *) pFXR->aValue + pPDat->usMultiOffset);
pusPtr+=2; /* Point to the current number of m-m fields */
/* Get ptr to beginning of current XR, scoot the rest down and insert
the 3-4 byte header at the end of the list. */
pInsert = MultiTypeIndex(pFXR->aValue+pPDat->usMultiOffset, *pusPtr);
memmove(pInsert+usSize,pInsert, pFXR->cbValue-(pInsert-pFXR->aValue));
memcpy(pInsert,aUtility,usSize);
pFXR->cbValue += usSize; /* Fix up the counts */
pPDat->cbMulti+= usSize;
/* Set the PDat for call */
PDat.Point = (CHAR *) pFXR;
PDat.cbMulti = pPDat->cbMulti;
PDat.usMultiOffset = pPDat->usMultiOffset;
PDat.usIndex = *pusPtr;
if(!EditXRValue(hwnd,&PDat)) /* They canceled the edit */
{ /* Move the XR's back to effectively kill the inserted header */
memmove(pInsert,pInsert+usSize,pFXR->cbValue-(pInsert-pFXR->aValue));
ResizeMem(pFXR->aValue,pFXR->cbValue,pFXR->cbValue-usSize);
pFXR->cbValue -= usSize; /* Adjust counters */
pPDat->cbMulti-= usSize;
return;
}
/* Reset pusPtr since EditXRValue could have moved the base address */
pusPtr = (USHORT *) ((CHAR *) pFXR->aValue + pPDat->usMultiOffset);
pusPtr+=2;
pInsert = MultiTypeIndex(pFXR->aValue+pPDat->usMultiOffset, *pusPtr);
*pusPtr += 1; /* Field cnt incremented AFTER call to Edit */
pValue = XRValueString(hwnd,pInsert); /* Add new field to the list box */
WinSendDlgItemMsg(hwnd, IDD_LBOX, LM_INSERTITEM,
MPFROM2SHORT(LIT_END,0),
MPFROMP(pValue));
FreeMem(pValue,strlen(pValue)+1);
FILE_CHANGED = TRUE;
}
/***************************************/
/***************************************/