|
|
/****************************************************************************/ /* */ /* rcx.C - AFX symbol info writer */ /* */ /* Windows 3.5 Resource Compiler */ /* */ /****************************************************************************/
#include "rc.h"
/////////////////////////////////////////////////////////////////////////////
// Symbol information
static PFILE fhFileMap; static LONG lFileMap;
static PFILE fhResMap; static LONG lResMap;
static PFILE fhRefMap; static LONG lRefMap;
static PFILE fhSymList; static LONG lSymList;
static LONG HdrOffset;
static CHAR szEndOfResource[2] = {'$', '\000'};
static CHAR szSymList[_MAX_PATH]; static CHAR szFileMap[_MAX_PATH]; static CHAR szRefMap[_MAX_PATH]; static CHAR szResMap[_MAX_PATH];
static WCHAR szName[] = L"HWB";
#define OPEN_FLAGS (_O_TRUNC | _O_BINARY | _O_CREAT | _O_RDWR)
#define PROT_FLAGS (S_IWRITE | S_IWRITE)
void wtoa( WORD value, char* string, int radix ) { if (value == (WORD)-1) _itoa(-1, string, radix); else _itoa(value, string, radix); }
int ConvertAndWrite( PFILE fp, PWCHAR pwch ) { int n; char szMultiByte[_MAX_PATH]; // assumes _MAX_PATH >= MAX_SYMBOL
n = wcslen(pwch) + 1; n = WideCharToMultiByte(uiCodePage, 0, pwch, n, szMultiByte, MAX_PATH, NULL, NULL); return MyWrite(fp, (PVOID)szMultiByte, n); }
VOID WriteResHdr ( FILE *fh, LONG size, WORD id ) { LONG val;
/* add data size and header size */ MyWrite(fh, (PVOID)&size, sizeof(ULONG)); // will backpatch
MyWrite(fh, (PVOID)&HdrOffset, sizeof(ULONG));
/* add type and name */ MyWrite(fh, (PVOID)szName, sizeof(szName)); val = 0xFFFF; MyWrite(fh, (PVOID)&val, sizeof(WORD)); MyWrite(fh, (PVOID)&id, sizeof(WORD));
MyAlign(fh);
/* add data struct version, flags, language, resource data version
/* and characteristics */ val = 0; MyWrite(fh, (PVOID)&val, sizeof(ULONG)); val = 0x0030; MyWrite(fh, (PVOID)&val, sizeof(WORD)); MyWrite(fh, (PVOID)&language, sizeof(WORD)); val = 2; MyWrite(fh, (PVOID)&val, sizeof(ULONG)); MyWrite(fh, (PVOID)&characteristics, sizeof(ULONG)); }
BOOL InitSymbolInfo( void ) { PCHAR szTmp;
if (!fAFXSymbols) return(TRUE);
if ((szTmp = _tempnam(NULL, "RCX1")) != NULL) { strcpy(szSymList, szTmp); free(szTmp); } else { strcpy(szSymList, tmpnam(NULL)); }
if ((szTmp = _tempnam(NULL, "RCX2")) != NULL) { strcpy(szFileMap, szTmp); free(szTmp); } else { strcpy(szFileMap, tmpnam(NULL)); }
if ((szTmp = _tempnam(NULL, "RCX3")) != NULL) { strcpy(szRefMap, szTmp); free(szTmp); } else { strcpy(szRefMap, tmpnam(NULL)); }
if ((szTmp = _tempnam(NULL, "RCX4")) != NULL) { strcpy(szResMap, szTmp); free(szTmp); } else { strcpy(szResMap, tmpnam(NULL)); }
if (!(fhFileMap = fopen(szFileMap, "w+b")) || !(fhSymList = fopen(szSymList, "w+b")) || !(fhRefMap = fopen(szRefMap, "w+b")) || !(fhResMap = fopen(szResMap, "w+b"))) return FALSE;
/* calculate header size */ HdrOffset = sizeof(szName); HdrOffset += 2 * sizeof(WORD); if (HdrOffset % 4) HdrOffset += sizeof(WORD); // could only be off by 2
HdrOffset += sizeof(RESADDITIONAL);
WriteResHdr(fhSymList, lSymList, 200); WriteResHdr(fhFileMap, lFileMap, 201); WriteResHdr(fhRefMap, lRefMap, 202); WriteResHdr(fhResMap, lResMap, 2);
return TRUE; }
BOOL TermSymbolInfo( PFILE fhResFile ) { long lStart; PTYPEINFO pType; RESINFO r;
if (!fAFXSymbols) return(TRUE);
if (fhResFile == NULL_FILE) goto termCloseOnly;
WriteSymbolDef(L"", L"", L"", 0, (char)0); MySeek(fhSymList, 0L, SEEK_SET); MyWrite(fhSymList, (PVOID)&lSymList, sizeof(lSymList));
MySeek(fhFileMap, 0L, SEEK_SET); MyWrite(fhFileMap, (PVOID)&lFileMap, sizeof(lFileMap));
WriteResInfo(NULL, NULL, FALSE); MySeek(fhRefMap, 0L, SEEK_SET); MyWrite(fhRefMap, (PVOID)&lRefMap, sizeof(lRefMap));
// now append these to .res
pType = AddResType(L"HWB", 0); r.flags = 0x0030; r.name = NULL; r.next = NULL; r.language = language; r.version = version; r.characteristics = characteristics;
MySeek(fhSymList, 0L, SEEK_SET); MyAlign(fhResFile); r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset; r.size = lSymList; r.nameord = 200; WriteResInfo(&r, pType, TRUE); MyCopyAll(fhSymList, fhResFile);
MySeek(fhFileMap, 0L, SEEK_SET); MyAlign(fhResFile); r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset; r.size = lFileMap; r.nameord = 201; WriteResInfo(&r, pType, TRUE); MyCopyAll(fhFileMap, fhResFile);
MySeek(fhRefMap, 0L, SEEK_SET); MyAlign(fhResFile); r.BinOffset = MySeek(fhResFile, 0L, SEEK_END) + HdrOffset; r.size = lRefMap; r.nameord = 202; WriteResInfo(&r, pType, TRUE); MyCopyAll(fhRefMap, fhResFile);
MyAlign(fhResFile); lStart = MySeek(fhResFile, 0L, SEEK_CUR); MySeek(fhResMap, 0L, SEEK_SET); MyWrite(fhResMap, (PVOID)&lResMap, sizeof(lResMap)); MySeek(fhResMap, 0L, SEEK_SET); MyCopyAll(fhResMap, fhResFile);
// patch the HWB:1 resource with HWB:2's starting point
MySeek(fhResFile, lOffIndex, SEEK_SET); MyWrite(fhResFile, (PVOID)&lStart, sizeof(lStart));
MySeek(fhResFile, 0L, SEEK_END);
termCloseOnly:;
if (fhFileMap) { fclose(fhFileMap); remove(szFileMap); }
if (fhRefMap) { fclose(fhRefMap); remove(szRefMap); }
if (fhSymList) { fclose(fhSymList); remove(szSymList); }
if (fhResMap) { fclose(fhResMap); remove(szResMap); }
return TRUE; }
void WriteSymbolUse( PSYMINFO pSym ) { if (!fAFXSymbols) return;
if (pSym == NULL) { WORD nID = (WORD)-1;
lRefMap += MyWrite(fhRefMap, (PVOID)&szEndOfResource, sizeof(szEndOfResource)); lRefMap += MyWrite(fhRefMap, (PVOID)&nID, sizeof(nID)); } else { lRefMap += ConvertAndWrite(fhRefMap, pSym->name); lRefMap += MyWrite(fhRefMap, (PVOID)&pSym->nID, sizeof(pSym->nID)); } }
void WriteSymbolDef( PWCHAR name, PWCHAR value, PWCHAR file, WORD line, char flags ) { if (!fAFXSymbols) return;
if (name[0] == L'$' && value[0] != L'\0') { RESINFO res; TYPEINFO typ;
res.nameord = (USHORT) -1; res.language = language; typ.typeord = (USHORT) -1; WriteFileInfo(&res, &typ, value); return; }
lSymList += ConvertAndWrite(fhSymList, name); lSymList += ConvertAndWrite(fhSymList, value);
lSymList += MyWrite(fhSymList, (PVOID)&line, sizeof(line)); lSymList += MyWrite(fhSymList, (PVOID)&flags, sizeof(flags)); }
void WriteFileInfo( PRESINFO pRes, PTYPEINFO pType, PWCHAR szFileName ) { WORD n1 = 0xFFFF;
if (!fAFXSymbols) return;
if (pType->typeord == 0) { lFileMap += MyWrite(fhFileMap, (PVOID)pType->type, (wcslen(pType->type) + 1) * sizeof(WCHAR)); } else { WORD n2 = pType->typeord;
if (n2 == (WORD)RT_MENUEX) n2 = (WORD)RT_MENU; else if (n2 == (WORD)RT_DIALOGEX) n2 = (WORD)RT_DIALOG; lFileMap += MyWrite(fhFileMap, (PVOID)&n1, sizeof(WORD)); lFileMap += MyWrite(fhFileMap, (PVOID)&n2, sizeof(WORD)); }
if (pRes->nameord == 0) { lFileMap += MyWrite(fhFileMap, (PVOID)pRes->name, (wcslen(pRes->name) + 1) * sizeof(WCHAR)); } else { lFileMap += MyWrite(fhFileMap, (PVOID)&n1, sizeof(WORD)); lFileMap += MyWrite(fhFileMap, (PVOID)&pRes->nameord, sizeof(WORD)); }
lFileMap += MyWrite(fhFileMap, (PVOID)&pRes->language, sizeof(WORD)); lFileMap += MyWrite(fhFileMap, (PVOID)szFileName, (wcslen(szFileName) + 1) * sizeof(WCHAR)); }
void WriteResInfo( PRESINFO pRes, PTYPEINFO pType, BOOL bWriteMapEntry ) { if (!fAFXSymbols) return;
if (pRes == NULL) { WORD nID = (WORD)-1;
//assert(bWriteMapEntry == FALSE);
lRefMap += MyWrite(fhRefMap, (PVOID)&szEndOfResource, sizeof(szEndOfResource)); lRefMap += MyWrite(fhRefMap, (PVOID)&nID, sizeof(nID));
return; }
if (bWriteMapEntry) { WORD n1 = 0xFFFF; ULONG t0 = 0;
/* add data size and data offset */ lResMap += MyWrite(fhResMap, (PVOID)&pRes->size, sizeof(ULONG)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->BinOffset, sizeof(ULONG));
/* Is this an ordinal type? */ if (pType->typeord) { WORD n2 = pType->typeord;
if (n2 == (WORD)RT_MENUEX) n2 = (WORD)RT_MENU; else if (n2 == (WORD)RT_DIALOGEX) n2 = (WORD)RT_DIALOG; lResMap += MyWrite(fhResMap, (PVOID)&n1, sizeof(WORD)); lResMap += MyWrite(fhResMap, (PVOID)&n2, sizeof(WORD)); } else { lResMap += MyWrite(fhResMap, (PVOID)pType->type, (wcslen(pType->type) + 1) * sizeof(WCHAR)); }
if (pRes->nameord) { lResMap += MyWrite(fhResMap, (PVOID)&n1, sizeof(WORD)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->nameord, sizeof(WORD)); } else { lResMap += MyWrite(fhResMap, (PVOID)pRes->name, (wcslen(pRes->name) + 1) * sizeof(WCHAR)); }
lResMap += MyAlign(fhResMap);
/* add data struct version, flags, language, resource data version
/* and characteristics */ lResMap += MyWrite(fhResMap, (PVOID)&t0, sizeof(ULONG)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->flags, sizeof(WORD)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->language, sizeof(WORD)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->version, sizeof(ULONG)); lResMap += MyWrite(fhResMap, (PVOID)&pRes->characteristics, sizeof(ULONG));
return; }
if (pType->typeord == 0) { lRefMap += ConvertAndWrite(fhRefMap, pType->type); } else { char szID[33]; WORD n2 = pType->typeord;
if (n2 == (WORD)RT_MENUEX) n2 = (WORD)RT_MENU; else if (n2 == (WORD)RT_DIALOGEX) n2 = (WORD)RT_DIALOG;
wtoa(n2, szID, 10); lRefMap += MyWrite(fhRefMap, (PVOID)szID, strlen(szID)+1); }
if (pRes->nameord == 0) { lRefMap += ConvertAndWrite(fhRefMap, pRes->name); } else { char szID[33];
wtoa(pRes->nameord, szID, 10); lRefMap += MyWrite(fhRefMap, (PVOID)szID, strlen(szID)+1); }
lRefMap += ConvertAndWrite(fhRefMap, pRes->sym.name); lRefMap += ConvertAndWrite(fhRefMap, pRes->sym.file); lRefMap += MyWrite(fhRefMap,(PVOID)&pRes->sym.line,sizeof(pRes->sym.line)); }
/*---------------------------------------------------------------------------*/ /* */ /* GetSymbolDef() - get a symbol def record and write out info */ /* */ /*---------------------------------------------------------------------------*/ void GetSymbolDef( int fReportError, WCHAR curChar ) { SYMINFO sym; WCHAR szDefn[_MAX_PATH]; WCHAR szLine[16]; PWCHAR p; CHAR flags = 0; WCHAR currentChar = curChar;
if (!fAFXSymbols) return;
currentChar = LitChar(); // get past SYMDEFSTART
/* read the symbol name */ p = sym.name; while ((*p++ = currentChar) != SYMDELIMIT) currentChar = LitChar(); *--p = L'\0'; if (p - sym.name > MAX_SYMBOL) { ParseError1(2247); return; } currentChar = LitChar(); /* read past the delimiter */
p = szDefn; while ((*p++ = currentChar) != SYMDELIMIT) currentChar = LitChar(); *--p = L'\0'; currentChar = LitChar(); /* read past the delimiter */
sym.file[0] = L'\0';
p = szLine; while ((*p++ = currentChar) != SYMDELIMIT) currentChar = LitChar(); *--p = L'\0'; sym.line = (WORD)wcsatoi(szLine); currentChar = LitChar(); /* read past the delimiter */
flags = (CHAR)currentChar; flags &= 0x7f; // clear the hi bit
currentChar = LitChar(); /* read past the delimiter */
/* leave positioned at last character (LitChar will bump) */ if (currentChar != SYMDELIMIT) { ParseError1(2248); }
WriteSymbolDef(sym.name, szDefn, sym.file, sym.line, flags); }
/*---------------------------------------------------------------------------*/ /* */ /* GetSymbol() - read a symbol and put id in the token if there */ /* */ /*---------------------------------------------------------------------------*/ void GetSymbol( int fReportError, WCHAR curChar ) { WCHAR currentChar = curChar;
token.sym.name[0] = L'\0'; token.sym.file[0] = L'\0'; token.sym.line = 0;
if (!fAFXSymbols) return;
/* skip whitespace */ while (iswhite(currentChar)) currentChar = LitChar();
if (currentChar == SYMUSESTART) { WCHAR * p; int i = 0; WCHAR szLine[16];
currentChar = LitChar(); // get past SYMUSESTART
if (currentChar != L'\"') { ParseError1(2249); return; } currentChar = LitChar(); // get past the first \"
/* read the symbol name */ p = token.sym.name; while ((*p++ = currentChar) != SYMDELIMIT) currentChar = LitChar(); *--p = L'\0'; if (p - token.sym.name > MAX_SYMBOL) { ParseError1(2247); return; } currentChar = LitChar(); /* read past the delimiter */
p = token.sym.file; while ((*p++ = currentChar) != SYMDELIMIT) currentChar = LitChar(); *--p = L'\0'; currentChar = LitChar(); /* read past the delimiter */
p = szLine; while ((*p++ = currentChar) != L'\"') currentChar = LitChar(); *--p = L'\0'; token.sym.line = (WORD)wcsatoi(szLine);
if (currentChar != L'\"') { ParseError1(2249); return; }
currentChar = LitChar(); // get past SYMDELIMIT
/* skip whitespace */ while (iswhite(currentChar)) currentChar = LitChar(); } }
|