////////////////////////////////////////////////////////////////////////// // // The format of the token file is: // [[TYPE ID|RES ID|Item ID|Flags|Status Flags|Item Name]]= // this is the standar format used by several token file tools in MS. // /////////////////////////////////////////////////////////////////////////////// // // Author: Alessandro Muti // Date: 12/02/94 // /////////////////////////////////////////////////////////////////////////////// #include #include "iodll.h" #include "main.h" #include "token.h" #include "vktbl.h" #include "imagehlp.h" extern CMainApp theApp; /*******************************************************\ This is the part were the real code starts. The function Bingen generate a binary from a token file. If the user select the -u options then we perform a token checking otherwise we'll be compatible with RLMAN and just trust the ID. \*******************************************************/ CMainApp::Error_Codes CMainApp::BinGen() { Error_Codes iErr = ERR_NOERROR; CTokenFile m_tokenfile; CToken * pToken; iErr = (CMainApp::Error_Codes)m_tokenfile.Open(m_strSrcTok, m_strTgtTok); if(iErr) { return iErr; } WriteCon(CONERR, "%s\r\n", CalcTab("", 79, '-')); // Copy the Src binary over the target // Now we can go and open an handle to the SrcExe file HANDLE hModule = RSOpenModule(m_strInExe, NULL); if ((int)(UINT_PTR)hModule < LAST_ERROR) { // error or warning WriteCon(CONERR, "%s", CalcTab(m_strInExe, m_strInExe.GetLength()+5, ' ')); IoDllError((int)(UINT_PTR)hModule); return ERR_FILE_NOTSUPP; } else { LPCSTR lpszType = 0L; LPCSTR lpszRes = 0L; DWORD dwLang = 0L; DWORD dwItem = 0L; DWORD dwItemId; LPRESITEM lpResItem = NULL; CString strResName = ""; BOOL bSkip; BOOL bSkipLang = FALSE; WORD wCount = 0; CString strFaceName; WORD wPointSize; BYTE bCharSet; // before we do anything else we have to check how many languages we have in the file CString strLang; char szLang[8]; BOOL b_multi_lang = FALSE; USHORT usInputLang = MAKELANGID(m_usIPriLangId, m_usISubLangId); if((b_multi_lang = RSLanguages(hModule, strLang.GetBuffer(1024))) && !IsFlag(INPUT_LANG)) { // this is a multiple language file but we don't have an input language specified // Fail, but warn the user that he has to set the input language to continue. strLang.ReleaseBuffer(); theApp.SetReturn(ERROR_FILE_MULTILANG); WriteCon(CONERR, "Multiple language file. Please specify an input language %s.\r\n", strLang); goto exit; } strLang.ReleaseBuffer(); // Convert the language in to the hex value if (usInputLang) sprintf(szLang,"0x%3X", usInputLang); else sprintf(szLang,"0x000"); // Check if the input language that we got is a valid one if(IsFlag(INPUT_LANG) && strLang.Find(szLang)==-1) { WriteCon(CONERR, "The language %s in not a valid language for this file.\r\n", szLang); WriteCon(CONERR, "Valid languages are: %s.\r\n", strLang); theApp.SetReturn(ERROR_RES_NOT_FOUND); goto exit; } CString strFileName = m_strInExe; CString strFileType; CString strTokenDir = ""; int pos = m_strInExe.ReverseFind('\\'); if(pos!=-1) { strFileName = m_strInExe.Right(m_strInExe.GetLength()-pos-1); } else if((pos = m_strInExe.ReverseFind(':'))!=-1) { strFileName = m_strInExe.Right(m_strInExe.GetLength()-pos-1); } pos = m_strTgtTok.ReverseFind('\\'); if(pos==-1) pos = m_strTgtTok.ReverseFind(':'); if(pos!=-1) strTokenDir = m_strTgtTok.Left(pos+1); if (m_strSymPath[0] && m_strSymPath != m_strOutputSymPath) { CString strInDebugFile; CString strOutDebugFile; HANDLE hDebugFile = FindDebugInfoFile( strFileName.GetBuffer(MAX_PATH), m_strSymPath.GetBuffer(MAX_PATH), strInDebugFile.GetBuffer(MAX_PATH) ); strInDebugFile.ReleaseBuffer(); if ( hDebugFile == NULL ) { return (Error_Codes)IoDllError(ERROR_IO_SYMBOLFILE_NOT_FOUND); } CloseHandle(hDebugFile); strOutDebugFile = m_strOutputSymPath + strInDebugFile.Right(strInDebugFile.GetLength()-m_strSymPath.GetLength()); if (!CopyFile(strInDebugFile.GetBuffer(MAX_PATH), strOutDebugFile.GetBuffer(MAX_PATH),FALSE)) { CString strTmp; strTmp = strOutDebugFile.Left(strOutDebugFile.GetLength()-strFileName.GetLength()-1); CreateDirectory(strTmp.GetBuffer(MAX_PATH),NULL); if (!CopyFile(strInDebugFile.GetBuffer(MAX_PATH), strOutDebugFile.GetBuffer(MAX_PATH),FALSE)) { return (Error_Codes)IoDllError(ERROR_FILE_SYMPATH_NOT_FOUND); } } } WriteCon(CONOUT, "Processing\t"); WriteCon(CONBOTH, "%s", CalcTab(strFileName, strFileName.GetLength()+5, ' ')); RSFileType(m_strInExe, strFileType.GetBuffer(10)); strFileType.ReleaseBuffer(); WriteCon(CONBOTH, "%s", CalcTab(strFileType, strFileType.GetLength()+5, ' ')); if(IsFlag(WARNING)) WriteCon(CONBOTH, "\r\n"); while ((lpszType = RSEnumResType(hModule, lpszType))) { // Check if is one of the type we care about if(HIWORD(lpszType)==0) switch(LOWORD(lpszType)) { case 1: case 2: case 3: case 4: case 5: case 6: case 9: case 10: case 11: case 12: case 14: case 16: case 23: case 240: case 1024: case 2110: bSkip = FALSE; break; default: bSkip = TRUE; } else bSkip = FALSE; lpszRes = 0L; dwLang = 0L; dwItem = 0L; CString strText; int iTokenErr = 0; while ((!bSkip) && (lpszRes = RSEnumResId(hModule, lpszType, lpszRes))) { while ((dwLang = RSEnumResLang(hModule, lpszType, lpszRes, dwLang))) { // Check if we have to skip this language if(b_multi_lang && (LOWORD(dwLang)!=usInputLang)) bSkipLang = TRUE; else bSkipLang = FALSE; while ((!bSkipLang) && (dwItem = RSEnumResItemId(hModule, lpszType, lpszRes, dwLang, dwItem))) { // Now Get the Data DWORD dwImageSize = RSGetResItemData( hModule, lpszType, lpszRes, dwLang, dwItem, m_pBuf, MAX_BUF_SIZE ); lpResItem = (LPRESITEM)m_pBuf; if(((wCount++ % 50)==0) && !(IsFlag(WARNING))) WriteCon(CONOUT, "."); if (HIWORD(lpszType)) { if (lstrcmp (lpszType,"REGINST") == 0) { // // Currently there is no id for REGINST defined // in nt. We just use this 2200 for now. // lpResItem->dwTypeID = 2200; } } lpResItem->dwLanguage = theApp.GetOutLang(); // Version stamp use class name as res id if(lpResItem->lpszResID) strResName = lpResItem->lpszResID; else strResName = ""; if(lpResItem->dwTypeID==16) { strResName = lpResItem->lpszClassName; } switch(LOWORD(lpResItem->dwTypeID)) { case 4: { if(!(lpResItem->dwFlags & MF_POPUP)) dwItemId = (LOWORD(lpResItem->dwItemID)==0xffff ? HIWORD(lpResItem->dwItemID) : lpResItem->dwItemID); else dwItemId = lpResItem->dwItemID; } break; case 5: dwItemId = (LOWORD(lpResItem->dwItemID)==0xffff ? HIWORD(lpResItem->dwItemID) : lpResItem->dwItemID); break; case 11: dwItemId = LOWORD(lpResItem->dwItemID); break; default: dwItemId = lpResItem->dwItemID; } if (lpResItem->dwTypeID==1 || lpResItem->dwTypeID==12 || lpResItem->dwTypeID==14) { // if user don't want to append redundant cursors, // bitmaps, and icons, we make it NULL if (IsFlag(LEANAPPEND) && IsFlag(APPEND)){ dwImageSize=0; RSUpdateResImage(hModule,lpszType,lpszRes,dwLang,0,lpResItem,dwImageSize); } continue; } // Is this a bitmap? if(lpResItem->dwTypeID==2 || lpResItem->dwTypeID==3 || lpResItem->dwTypeID==23 || lpResItem->dwTypeID== 240 || lpResItem->dwTypeID== 1024 || lpResItem->dwTypeID== 2110 || lpResItem->dwTypeID== 2200) { if (IsFlag(LEANAPPEND) && IsFlag(APPEND) && (lpResItem->dwTypeID == 2 || lpResItem->dwTypeID == 3)) { dwImageSize=0; RSUpdateResImage(hModule,lpszType,lpszRes,dwLang,0,lpResItem,dwImageSize); continue; } // Search for a token with this ID pToken = (CToken *)m_tokenfile.GetNoCaptionToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, strResName); if(pToken!=NULL) { // Get the name of the input image strText = pToken->GetTgtText(); // Open the file CFile inputFile; if(!inputFile.Open(strText, CFile::modeRead | CFile::shareDenyNone | CFile::typeBinary ) && !inputFile.Open(strTokenDir + strText, CFile::modeRead | CFile::shareDenyNone | CFile::typeBinary)) { WriteCon(CONERR, "Input file %s not found! Using Src file data!\r\n", strTokenDir+strText); goto skip; } DWORD dwSize = inputFile.GetLength(); BYTE * pInputBuf = (BYTE*)new BYTE[dwSize]; if(pInputBuf==NULL) { WriteCon(CONERR, "Error allocating memory for the image! (%d)\r\n", dwSize); goto skip; } BYTE * pInputBufOrigin = pInputBuf; inputFile.ReadHuge(pInputBuf, inputFile.GetLength()); CString strTmp = pToken->GetTokenID(); WriteCon(CONWRN, "Using image in file %s for ID %s\"]]!\r\n", strText.GetBuffer(0), strTmp.GetBuffer(0)); BYTE * pInputImage=(BYTE *) new BYTE[dwSize]; DWORD dwImageSize; // remove the header from the file switch(lpResItem->dwTypeID) { case 2: { dwImageSize = dwSize - sizeof(BITMAPFILEHEADER); pInputBuf += sizeof(BITMAPFILEHEADER); } break; case 3: { dwImageSize = dwSize - sizeof(ICONHEADER); pInputBuf += sizeof(ICONHEADER); } case 23: case 240: case 1024: case 2110: case 2200: { dwImageSize = dwSize; } break; default: break; } memcpy(pInputImage, pInputBuf, dwImageSize); // // We need to keep output lang info seperately, // because we dont't have lpResItem to send // the info to io for icons and bitmaps. // DWORD dwUpdLang = theApp.GetOutLang(); // Update the resource RSUpdateResImage(hModule,lpszType,lpszRes,dwLang,dwUpdLang, pInputImage,dwImageSize); delete pInputBufOrigin; delete pInputImage; } else { goto skip; } } // is this an accelerator else if(lpResItem->dwTypeID==9) { // Search for a token with this ID pToken = (CToken *)m_tokenfile.GetNoCaptionToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, strResName); if(pToken!=NULL) { CAccel acc(pToken->GetTgtText()); if( (lpResItem->dwFlags & 0x80)==0x80 ) lpResItem->dwFlags = acc.GetFlags() | 0x80; else lpResItem->dwFlags = acc.GetFlags(); lpResItem->dwStyle = acc.GetEvent(); if(IoDllError(RSUpdateResItemData(hModule,lpszType,lpszRes,dwLang,dwItem,lpResItem,MAX_BUF_SIZE))) { // we have an error, warn the user WriteCon(CONWRN, "Error updating token\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); } } } else { // Search for a token with this ID pToken = (CToken *)m_tokenfile.GetToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, Format(lpResItem->lpszCaption), strResName); } if(pToken!=NULL) { iTokenErr = pToken->GetLastError(); if(pToken->GetFlags() & ISEXTSTYLE){ CString strStyle= pToken->GetTgtText(); lpResItem->dwExtStyle = strtol(strStyle, (char**)0,16); // Get the real Token pToken = (CToken *)m_tokenfile.GetToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, Format(lpResItem->lpszCaption), strResName); if(pToken!=NULL) wCount++; } // Check if is a dialog font name if(pToken != NULL && ((pToken->GetFlags() & ISDLGFONTNAME) || (pToken->GetFlags() & ISDLGFONTSIZE))) { if(theApp.IsFlag(CMainApp::FONTS)) { int iColon; CString strTgtFaceName = pToken->GetTgtText(); // This should be the font description token if( strTgtFaceName.IsEmpty() || ((iColon = strTgtFaceName.Find(':'))==-1) ) WriteCon(CONWRN, "Using Src file FaceName for ID %s\"]]!\r\n", pToken->GetTokenID()); // Check if the dialog has the DS_SETFONT flag set, otherwise let the user // know that we can't do much with his font description if( (lpResItem->dwStyle & DS_SETFONT)!=DS_SETFONT ) WriteCon(CONWRN, "Dialog ID %s\"]] is missing the DS_SETFONT bit. Cannot change font!\r\n", pToken->GetTokenID()); else { strFaceName = strTgtFaceName.Left(iColon); strFaceName.TrimRight(); strTgtFaceName = strTgtFaceName.Right(strTgtFaceName.GetLength() - iColon-1); strTgtFaceName.TrimLeft(); //sscanf( strTgtFaceName, "%d", &wPointSize ); if ((iColon=strTgtFaceName.Find(':'))!=-1) { wPointSize=(WORD)atoi(strTgtFaceName.Left(iColon)); strTgtFaceName = strTgtFaceName.Right(strTgtFaceName.GetLength() - iColon-1); bCharSet = (BYTE)atoi(strTgtFaceName); lpResItem->bCharSet = bCharSet; }else{ wPointSize=(WORD)atoi(strTgtFaceName); } lpResItem->lpszFaceName = strFaceName.GetBuffer(0); lpResItem->wPointSize = wPointSize; strFaceName.ReleaseBuffer(); } } // Get the real Token pToken = (CToken *)m_tokenfile.GetToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, Format(lpResItem->lpszCaption), strResName); if(pToken!=NULL) wCount++; } } if(pToken!=NULL && !pToken->GetLastError()) { strText = UnFormat(pToken->GetTgtText()); if(m_tokenfile.GetTokenSize(pToken, &lpResItem->wX, &lpResItem->wY, &lpResItem->wcX, &lpResItem->wcY)) wCount++; lpResItem->lpszCaption = strText.GetBuffer(0); // Static control and style flag is set. We need // to take style alignment change as well if (LOBYTE(lpResItem->wClassName) == 0x82 && theApp.IsFlag(CMainApp::ALIGNMENT)) { //Get style alignment token pToken = (CToken *)m_tokenfile.GetToken( lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, Format(lpResItem->lpszCaption), strResName); if (pToken!=NULL) { wCount++; CString strStyle=pToken->GetTgtText(); if (strStyle=="SS_CENTER") lpResItem->dwStyle |= SS_CENTER; else if (strStyle=="SS_RIGHT") { //reset the alignment bit lpResItem->dwStyle &= 0xfffffffc; lpResItem->dwStyle |= SS_RIGHT; } else if (strStyle=="SS_LEFT") lpResItem->dwStyle &= 0xfffffffc; else //use provided style is wrong. warn! WriteCon(CONWRN, "Using Src file alignment style for ID %s\"]]!\r\n", pToken->GetTokenID()); } } if(IoDllError(RSUpdateResItemData(hModule,lpszType,lpszRes,dwLang,dwItem,lpResItem,MAX_BUF_SIZE))) { // we have an error, warn the user WriteCon(CONWRN, "Error updating token\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); } strText.ReleaseBuffer(); } else { pToken = (CToken *)m_tokenfile.GetNoCaptionToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, strResName); if(pToken!=NULL) { if(pToken->GetFlags() & ISEXTSTYLE){ CString strStyle= pToken->GetTgtText(); lpResItem->dwExtStyle = strtol(strStyle, (char**)0,16); // Get the real Token pToken = (CToken *)m_tokenfile.GetNoCaptionToken(lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, strResName); if(pToken!=NULL) wCount++; } // Check if is a dialog font name if(pToken != NULL && ((pToken->GetFlags() & ISDLGFONTNAME) || (pToken->GetFlags() & ISDLGFONTSIZE))) { if(theApp.IsFlag(CMainApp::FONTS)) { int iColon; CString strTgtFaceName = pToken->GetTgtText(); // This should be the font description token if( strTgtFaceName.IsEmpty() || ((iColon = strTgtFaceName.Find(':'))==-1) ) WriteCon(CONWRN, "Using Src file FaceName for ID %s\"]]!\r\n", pToken->GetTokenID()); // Check if the dialog has the DS_SETFONT flag set, otherwise let the user // know that we can't do much with his font description if( (lpResItem->dwStyle & DS_SETFONT)!=DS_SETFONT ) WriteCon(CONWRN, "Dialog ID %s\"]] is missing the DS_SETFONT bit. Cannot change font!\r\n", pToken->GetTokenID()); else { strFaceName = strTgtFaceName.Left(iColon); strFaceName.TrimRight(); strTgtFaceName = strTgtFaceName.Right(strTgtFaceName.GetLength() - iColon-1); strTgtFaceName.TrimLeft(); // sscanf( strTgtFaceName, "%d", &wPointSize ); if ((iColon=strTgtFaceName.Find(':'))!=-1){ wPointSize=(WORD)atoi(strTgtFaceName.Left(iColon)); strTgtFaceName = strTgtFaceName.Right(strTgtFaceName.GetLength() - iColon-1); bCharSet = (BYTE)atoi(strTgtFaceName); lpResItem->bCharSet = bCharSet; }else{ wPointSize=(WORD)atoi(strTgtFaceName); } lpResItem->lpszFaceName = strFaceName.GetBuffer(0); lpResItem->wPointSize = wPointSize; strFaceName.ReleaseBuffer(); } } if(m_tokenfile.GetTokenSize(pToken, &lpResItem->wX, &lpResItem->wY, &lpResItem->wcX, &lpResItem->wcY)) wCount++; } // Check if is a dialog size else if(pToken->GetFlags() & ISCOR) { pToken->GetTgtSize(&lpResItem->wX, &lpResItem->wY, &lpResItem->wcX, &lpResItem->wcY); } // Just size and/or font updated if(IoDllError(RSUpdateResItemData(hModule,lpszType,lpszRes,dwLang,dwItem,lpResItem,MAX_BUF_SIZE))) { // we have an error, warn the user WriteCon(CONWRN, "Error updating token\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); } } else { switch(LOWORD(lpszType)) { case 4: case 5: case 6: case 10: case 11: // No Token was found for this ID // Leave it for now but here will come the // PSEUDO Translation code. if(strlen(lpResItem->lpszCaption) && !iTokenErr) { WriteCon(CONWRN, "ID not found\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); } break; case 9: WriteCon(CONWRN, "ID not found\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); break; break; case 16: if (theApp.IsFlag(CMainApp::NOVERSION) && (strResName==TEXT("FileVersion") || strResName==TEXT("ProductVersion") || strResName==TEXT("Platform"))){ // // do nothing // }else if(strlen(lpResItem->lpszCaption) && !iTokenErr){ WriteCon(CONWRN, "ID not found\t[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]\r\n", lpResItem->dwTypeID, lpResItem->dwResID, dwItemId, 0, 4, strResName); AddNotFound(); } break; default: break; } // Let's update the item anyway, since the language might have changed // RSUpdateResItemData(hModule,lpszType,lpszRes,dwLang,dwItem,lpResItem,MAX_BUF_SIZE); } } skip:; } } } } iErr=(Error_Codes)IoDllError(RSWriteResFile(hModule, m_strOutExe, NULL,m_strOutputSymPath)); if ((int)iErr > 0){ //WriteCon(CONERR, "%s", CalcTab(m_strOutExe, m_strOutExe.GetLength()+5, ' ')); goto exit; } WriteCon(CONBOTH, " %hu(%hu) Items\r\n", wCount, m_wIDNotFound); // Check if some items were removed from the file if(wCount