Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

850 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // File: rwinf.cpp
  4. //
  5. // Contents: Implementation for the Windows NT 3.51 inf Read/Write module
  6. //
  7. // Classes:
  8. //
  9. // History: 13-Mar-95 alessanm created
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include <afxdllx.h>
  14. #include "inf.h"
  15. #include "..\common\helper.h"
  16. #ifdef _DEBUG
  17. #undef THIS_FILE
  18. static char BASED_CODE THIS_FILE[] = __FILE__;
  19. #endif
  20. /////////////////////////////////////////////////////////////////////////////
  21. // General Declarations
  22. #define RWTAG "INF"
  23. #define INF_TYPE 11
  24. #define MAX_INF_TEXT_LINE 55
  25. #define Pad4(x) ((((x+3)>>2)<<2)-x)
  26. typedef struct tagUpdResList
  27. {
  28. WORD * pTypeId;
  29. BYTE * pTypeName;
  30. WORD * pResId;
  31. BYTE * pResName;
  32. DWORD * pLang;
  33. DWORD * pSize;
  34. struct tagUpdResList* pNext;
  35. } UPDATEDRESLIST, *PUPDATEDRESLIST;
  36. class CLoadedFile : public CObject
  37. {
  38. public:
  39. CLoadedFile(LPCSTR lpfilename);
  40. CInfFile m_infFile;
  41. CString m_strFileName;
  42. };
  43. CLoadedFile::CLoadedFile(LPCSTR lpfilename)
  44. {
  45. TRY
  46. {
  47. m_infFile.Open(lpfilename, CFile::modeRead | CFile::shareDenyNone);
  48. }
  49. CATCH(CFileException, pfe)
  50. {
  51. AfxThrowFileException(pfe->m_cause, pfe->m_lOsError);
  52. }
  53. END_CATCH
  54. m_strFileName = lpfilename;
  55. }
  56. /////////////////////////////////////////////////////////////////////////////
  57. // Function Declarations
  58. LONG
  59. WriteResInfo(
  60. BYTE** lplpBuffer, LONG* plBufSize,
  61. WORD wTypeId, LPCSTR lpszTypeId, BYTE bMaxTypeLen,
  62. WORD wNameId, LPCSTR lpszNameId, BYTE bMaxNameLen,
  63. DWORD dwLang,
  64. DWORD dwSize, DWORD dwFileOffset );
  65. CInfFile * LoadFile(LPCSTR lpfilename);
  66. PUPDATEDRESLIST CreateUpdateResList(BYTE * lpBuffer, UINT uiBufSize);
  67. PUPDATEDRESLIST FindId(LPCSTR pstrId, PUPDATEDRESLIST pList);
  68. /////////////////////////////////////////////////////////////////////////////
  69. // Public C interface implementation
  70. CObArray g_LoadedFile;
  71. //[registration]
  72. extern "C"
  73. BOOL FAR PASCAL RWGetTypeString(LPSTR lpszTypeName)
  74. {
  75. strcpy( lpszTypeName, RWTAG );
  76. return FALSE;
  77. }
  78. extern "C"
  79. BOOL FAR PASCAL RWValidateFileType(LPCSTR lpszFilename)
  80. {
  81. TRACE("RWINF.DLL: RWValidateFileType()\n");
  82. // Check file exstension and try to open it
  83. if(strstr(lpszFilename, ".INF")!=NULL || strstr(lpszFilename, ".inf")!=NULL)
  84. return TRUE;
  85. return FALSE;
  86. }
  87. extern "C"
  88. DllExport
  89. UINT
  90. APIENTRY
  91. RWReadTypeInfo(
  92. LPCSTR lpszFilename,
  93. LPVOID lpBuffer,
  94. UINT* puiSize
  95. )
  96. {
  97. TRACE("RWINF.DLL: RWReadTypeInfo()\n");
  98. UINT uiError = ERROR_NO_ERROR;
  99. if (!RWValidateFileType(lpszFilename))
  100. return ERROR_RW_INVALID_FILE;
  101. //
  102. // Open the file
  103. //
  104. CInfFile * pinfFile;
  105. TRY
  106. {
  107. pinfFile = LoadFile(lpszFilename);
  108. }
  109. CATCH(CFileException, pfe)
  110. {
  111. return pfe->m_cause + IODLL_LAST_ERROR;
  112. }
  113. END_CATCH
  114. //
  115. // Read the data and fill the iodll buffer
  116. //
  117. // Get to the beginning of the localization section
  118. //
  119. if(!pinfFile->SeekToLocalize())
  120. return ERROR_RW_NO_RESOURCES;
  121. CString strSection;
  122. CString strLine;
  123. CString strTag;
  124. CInfLine infLine;
  125. BYTE ** pBuf = (BYTE**)&lpBuffer;
  126. LONG lBufSize = 0;
  127. while(pinfFile->ReadTextSection(strSection))
  128. {
  129. while(pinfFile->ReadSectionString(infLine))
  130. {
  131. strTag = strSection + '.' + infLine.GetTag();
  132. lBufSize += WriteResInfo(
  133. pBuf, (LONG*)puiSize,
  134. INF_TYPE, "", 0,
  135. 0, strTag, 255,
  136. 0l,
  137. infLine.GetTextLength()+1, pinfFile->GetLastFilePos() );
  138. }
  139. }
  140. *puiSize = lBufSize;
  141. return uiError;
  142. }
  143. extern "C"
  144. DllExport
  145. DWORD
  146. APIENTRY
  147. RWGetImage(
  148. LPCSTR lpszFilename,
  149. DWORD dwImageOffset,
  150. LPVOID lpBuffer,
  151. DWORD dwSize
  152. )
  153. {
  154. UINT uiError = ERROR_NO_ERROR;
  155. //
  156. // Open the file
  157. //
  158. CInfFile * pinfFile;
  159. TRY
  160. {
  161. pinfFile = LoadFile(lpszFilename);
  162. }
  163. CATCH(CFileException, pfe)
  164. {
  165. return pfe->m_cause + IODLL_LAST_ERROR;
  166. }
  167. END_CATCH
  168. //
  169. // Seek to the string to retrieve and read it
  170. //
  171. CInfLine infLine;
  172. pinfFile->Seek( dwImageOffset, SEEK_SET );
  173. pinfFile->ReadSectionString(infLine);
  174. //
  175. // Fill the buffer with the string
  176. //
  177. if(infLine.GetTextLength()+1<=(LONG)dwSize)
  178. {
  179. memcpy(lpBuffer, infLine.GetText(), infLine.GetTextLength()+1);
  180. uiError = infLine.GetTextLength()+1;
  181. }
  182. else
  183. uiError = 0;
  184. return (DWORD)uiError;
  185. }
  186. extern "C"
  187. DllExport
  188. UINT
  189. APIENTRY
  190. RWParseImage(
  191. LPCSTR lpszType,
  192. LPVOID lpImageBuf,
  193. DWORD dwImageSize,
  194. LPVOID lpBuffer,
  195. DWORD dwSize
  196. )
  197. {
  198. UINT uiSizeOfDataStruct = strlen((LPCSTR)lpImageBuf)+sizeof(RESITEM);
  199. if(uiSizeOfDataStruct<=dwSize)
  200. {
  201. //
  202. // We have to fill the RESITEM Struct
  203. //
  204. LPRESITEM pResItem = (LPRESITEM)lpBuffer;
  205. memset(pResItem, '\0', uiSizeOfDataStruct);
  206. pResItem->dwSize = uiSizeOfDataStruct;
  207. pResItem->lpszCaption = (LPSTR)memcpy( ((BYTE*)pResItem)+sizeof(RESITEM), lpImageBuf, dwImageSize); // Caption
  208. }
  209. return uiSizeOfDataStruct;
  210. }
  211. extern"C"
  212. DllExport
  213. UINT
  214. APIENTRY
  215. RWWriteFile(
  216. LPCSTR lpszSrcFilename,
  217. LPCSTR lpszTgtFilename,
  218. HANDLE hResFileModule,
  219. LPVOID lpBuffer,
  220. UINT uiSize,
  221. HINSTANCE hDllInst,
  222. LPCSTR lpszSymbolPath
  223. )
  224. {
  225. UINT uiError = ERROR_NO_ERROR;
  226. // Get the handle to the IODLL
  227. hDllInst = LoadLibrary("iodll.dll");
  228. if (!hDllInst)
  229. return ERROR_DLL_LOAD;
  230. DWORD (FAR PASCAL * lpfnGetImage)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD);
  231. // Get the pointer to the function to extract the resources image
  232. lpfnGetImage = (DWORD (FAR PASCAL *)(HANDLE, LPCSTR, LPCSTR, DWORD, LPVOID, DWORD))
  233. GetProcAddress( hDllInst, "RSGetResImage" );
  234. if (lpfnGetImage==NULL) {
  235. FreeLibrary(hDllInst);
  236. return ERROR_DLL_LOAD;
  237. }
  238. //
  239. // Get the handle to the source file
  240. //
  241. CInfFile * psrcinfFile;
  242. TRY
  243. {
  244. psrcinfFile = LoadFile(lpszSrcFilename);
  245. }
  246. CATCH(CFileException, pfe)
  247. {
  248. return pfe->m_cause + IODLL_LAST_ERROR;
  249. }
  250. END_CATCH
  251. //
  252. // Create the target file
  253. //
  254. CFile tgtFile;
  255. CFileException fe;
  256. if(!tgtFile.Open(lpszTgtFilename, CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone, &fe))
  257. {
  258. return fe.m_cause + IODLL_LAST_ERROR;
  259. }
  260. //
  261. // Copy the part of the file that is not localizable
  262. //
  263. LONG lLocalize = psrcinfFile->SeekToLocalize();
  264. const BYTE * pStart = psrcinfFile->GetBuffer();
  265. if(lLocalize==-1)
  266. {
  267. // the file has no localizable info in it just copy it
  268. lLocalize = psrcinfFile->SeekToEnd();
  269. }
  270. TRY
  271. {
  272. tgtFile.Write(pStart, lLocalize);
  273. }
  274. CATCH(CFileException, pfe)
  275. {
  276. return pfe->m_cause + IODLL_LAST_ERROR;
  277. }
  278. END_CATCH
  279. //
  280. // Create the list of updated resources
  281. //
  282. PUPDATEDRESLIST pResList = CreateUpdateResList((BYTE*)lpBuffer, uiSize);
  283. //
  284. // What we have now is a part that is mized. Part of it has localizable
  285. // information and part has none.
  286. // We will read each section and decide if is a localizable section or not.
  287. // If it is we will update it otherwise just copy it
  288. //
  289. CString strSection, str;
  290. CString strLang = psrcinfFile->GetLanguage();
  291. LONG lEndPos, lStartPos;
  292. CInfLine infLine;
  293. while(psrcinfFile->ReadSection(strSection))
  294. {
  295. TRY
  296. {
  297. tgtFile.Write(strSection, strSection.GetLength());
  298. tgtFile.Write("\r\n", 2);
  299. }
  300. CATCH(CFileException, pfe)
  301. {
  302. return pfe->m_cause + IODLL_LAST_ERROR;
  303. }
  304. END_CATCH
  305. if(strSection.Find(strLang)==-1)
  306. {
  307. //
  308. // This is not a localizable section
  309. //
  310. lStartPos = psrcinfFile->Seek(0, SEEK_CUR);
  311. //
  312. // Read the next section untill we find a localizable section
  313. //
  314. while(psrcinfFile->ReadSection(strSection))
  315. {
  316. if(strSection.Find(strLang)!=-1)
  317. break;
  318. }
  319. //
  320. // Where are we now?
  321. //
  322. lEndPos = psrcinfFile->Seek(0, SEEK_CUR) - strSection.GetLength()-2;
  323. //
  324. // Make sure we are not at the end of the file
  325. //
  326. if(lEndPos<=lStartPos)
  327. {
  328. // we have no more section so copy all is left
  329. lEndPos = psrcinfFile->Seek(0, SEEK_END) - 1;
  330. }
  331. //
  332. // copy the full block
  333. //
  334. pStart = psrcinfFile->GetBuffer(lStartPos);
  335. TRY
  336. {
  337. tgtFile.Write(pStart, lEndPos-lStartPos);
  338. }
  339. CATCH(CFileException, pfe)
  340. {
  341. return pfe->m_cause + IODLL_LAST_ERROR;
  342. }
  343. END_CATCH
  344. psrcinfFile->Seek(lEndPos, SEEK_SET);
  345. }
  346. else
  347. {
  348. //
  349. // This is a localizable section
  350. // Read all the strings and see if they have been updated
  351. //
  352. CString strId;
  353. PUPDATEDRESLIST pListItem;
  354. BYTE * pByte;
  355. lEndPos = psrcinfFile->Seek(0, SEEK_CUR);
  356. while(psrcinfFile->ReadSectionString(str))
  357. {
  358. str += "\r\n";
  359. infLine = str;
  360. //
  361. // Check if we need to update this string
  362. //
  363. strId = strSection + "." + infLine.GetTag();
  364. if(pListItem = FindId(strId, pResList))
  365. {
  366. // allocate the buffer to hold the resource data
  367. pByte = new BYTE[*pListItem->pSize];
  368. if(!pByte){
  369. uiError = ERROR_NEW_FAILED;
  370. goto exit;
  371. }
  372. // get the data from the iodll
  373. LPSTR lpType = NULL;
  374. LPSTR lpRes = NULL;
  375. if (*pListItem->pTypeId) {
  376. lpType = (LPSTR)((WORD)*pListItem->pTypeId);
  377. } else {
  378. lpType = (LPSTR)pListItem->pTypeName;
  379. }
  380. if (*pListItem->pResId) {
  381. lpRes = (LPSTR)((WORD)*pListItem->pResId);
  382. } else {
  383. lpRes = (LPSTR)pListItem->pResName;
  384. }
  385. DWORD dwImageBufSize = (*lpfnGetImage)( hResFileModule,
  386. lpType,
  387. lpRes,
  388. *pListItem->pLang,
  389. pByte,
  390. *pListItem->pSize
  391. );
  392. if(dwImageBufSize!=*pListItem->pSize)
  393. {
  394. // something is wrong...
  395. delete []pByte;
  396. }
  397. else {
  398. infLine.ChangeText((LPCSTR)pByte);
  399. //
  400. // Now we have the updated image...
  401. //
  402. //
  403. // Check how long is the Data and split it in to lines
  404. //
  405. if(infLine.GetTextLength()>MAX_INF_TEXT_LINE)
  406. {
  407. //
  408. // First write the tag
  409. //
  410. str = infLine.GetData();
  411. int iSpaceLen = str.Find('=')+1;
  412. int iTagLen = 0;
  413. TRY
  414. {
  415. tgtFile.Write(str, iSpaceLen);
  416. }
  417. CATCH(CFileException, pfe)
  418. {
  419. return pfe->m_cause + IODLL_LAST_ERROR;
  420. }
  421. END_CATCH
  422. //
  423. // Now write the rest
  424. //
  425. int iExtra, iMaxStr;
  426. CString strLine;
  427. CString strSpace( ' ', iSpaceLen+1 );
  428. BOOL bFirstLine = TRUE;
  429. strSpace += '\"';
  430. str = infLine.GetText();
  431. str.TrimLeft();
  432. while(str.GetLength()>MAX_INF_TEXT_LINE)
  433. {
  434. iMaxStr = str.GetLength();
  435. strLine = str.Left(MAX_INF_TEXT_LINE);
  436. //
  437. // Check if we are in the middle of a word
  438. //
  439. iExtra = 0;
  440. while((iMaxStr>MAX_INF_TEXT_LINE+iExtra) && str.GetAt(MAX_INF_TEXT_LINE+iExtra)!=' ')
  441. {
  442. strLine += str.GetAt(MAX_INF_TEXT_LINE+iExtra++);
  443. }
  444. //
  445. // Make sure the spaces are the last thing
  446. //
  447. while((iMaxStr>MAX_INF_TEXT_LINE+iExtra) && str.GetAt(MAX_INF_TEXT_LINE+iExtra)==' ')
  448. {
  449. strLine += str.GetAt(MAX_INF_TEXT_LINE+iExtra++);
  450. }
  451. str = str.Mid(MAX_INF_TEXT_LINE+iExtra);
  452. if(str.IsEmpty())
  453. {
  454. //
  455. // This string is all done write it as is, we can't break it
  456. //
  457. strLine += "\r\n";
  458. }
  459. else strLine += "\"+\r\n";
  460. if(bFirstLine)
  461. {
  462. strLine = " " + strLine;
  463. bFirstLine = FALSE;
  464. } else
  465. {
  466. strLine = strSpace + strLine;
  467. }
  468. TRY
  469. {
  470. tgtFile.Write(strLine, strLine.GetLength());
  471. }
  472. CATCH(CFileException, pfe)
  473. {
  474. return pfe->m_cause + IODLL_LAST_ERROR;
  475. }
  476. END_CATCH
  477. //str = str.Mid(MAX_INF_TEXT_LINE+iExtra);
  478. }
  479. if(bFirstLine)
  480. {
  481. strLine = " " + str;
  482. } else
  483. {
  484. if(!str.IsEmpty())
  485. strLine = strSpace + str;
  486. else strLine = "";
  487. }
  488. if(!strLine.IsEmpty())
  489. {
  490. TRY
  491. {
  492. tgtFile.Write(strLine, strLine.GetLength());
  493. tgtFile.Write("\r\n", 2);
  494. }
  495. CATCH(CFileException, pfe)
  496. {
  497. return pfe->m_cause + IODLL_LAST_ERROR;
  498. }
  499. END_CATCH
  500. }
  501. }
  502. else
  503. {
  504. TRY
  505. {
  506. tgtFile.Write(infLine.GetData(), infLine.GetDataLength());
  507. tgtFile.Write("\r\n", 2);
  508. }
  509. CATCH(CFileException, pfe)
  510. {
  511. return pfe->m_cause + IODLL_LAST_ERROR;
  512. }
  513. END_CATCH
  514. }
  515. delete []pByte;
  516. }
  517. }
  518. else
  519. {
  520. TRY
  521. {
  522. tgtFile.Write(infLine.GetData(), infLine.GetDataLength());
  523. }
  524. CATCH(CFileException, pfe)
  525. {
  526. return pfe->m_cause + IODLL_LAST_ERROR;
  527. }
  528. END_CATCH
  529. }
  530. lEndPos = psrcinfFile->Seek(0, SEEK_CUR);
  531. }
  532. }
  533. }
  534. exit:
  535. tgtFile.Close();
  536. if(pResList)
  537. delete []pResList;
  538. return uiError;
  539. }
  540. extern "C"
  541. DllExport
  542. UINT
  543. APIENTRY
  544. RWUpdateImage(
  545. LPCSTR lpszType,
  546. LPVOID lpNewBuf,
  547. DWORD dwNewSize,
  548. LPVOID lpOldImage,
  549. DWORD dwOldImageSize,
  550. LPVOID lpNewImage,
  551. DWORD* pdwNewImageSize
  552. )
  553. {
  554. UINT uiError = ERROR_NO_ERROR;
  555. //
  556. // Get the new string
  557. //
  558. LPCSTR lpNewStr = (LPCSTR)(((LPRESITEM)lpNewBuf)->lpszCaption);
  559. //
  560. // Copy the string in the new image buffer
  561. //
  562. int iLen = strlen(lpNewStr)+1;
  563. if(iLen<=(LONG)*pdwNewImageSize)
  564. {
  565. memcpy(lpNewImage, lpNewStr, iLen);
  566. }
  567. *pdwNewImageSize = iLen;
  568. return uiError;
  569. }
  570. ///////////////////////////////////////////////////////////////////////////
  571. // Functions implementation
  572. //=============================================================================
  573. // WriteResInfo
  574. //
  575. // Fill the buffer to pass back to the iodll
  576. //=============================================================================
  577. LONG WriteResInfo(
  578. BYTE** lplpBuffer, LONG* plBufSize,
  579. WORD wTypeId, LPCSTR lpszTypeId, BYTE bMaxTypeLen,
  580. WORD wNameId, LPCSTR lpszNameId, BYTE bMaxNameLen,
  581. DWORD dwLang,
  582. DWORD dwSize, DWORD dwFileOffset )
  583. {
  584. LONG lSize = 0;
  585. lSize = PutWord( lplpBuffer, wTypeId, plBufSize );
  586. lSize += PutStringA( lplpBuffer, (LPSTR)lpszTypeId, plBufSize ); // Note: PutStringA should get LPCSTR and not LPSTR
  587. lSize += Allign( lplpBuffer, plBufSize, lSize);
  588. lSize += PutWord( lplpBuffer, wNameId, plBufSize );
  589. lSize += PutStringA( lplpBuffer, (LPSTR)lpszNameId, plBufSize );
  590. lSize += Allign( lplpBuffer, plBufSize, lSize);
  591. lSize += PutDWord( lplpBuffer, dwLang, plBufSize );
  592. lSize += PutDWord( lplpBuffer, dwSize, plBufSize );
  593. lSize += PutDWord( lplpBuffer, dwFileOffset, plBufSize );
  594. return (LONG)lSize;
  595. }
  596. CInfFile * LoadFile(LPCSTR lpfilename)
  597. {
  598. // Check if we have loaded the file before
  599. int c = (int)g_LoadedFile.GetSize();
  600. CLoadedFile * pLoaded;
  601. while(c)
  602. {
  603. pLoaded = (CLoadedFile*)g_LoadedFile.GetAt(--c);
  604. if(pLoaded->m_strFileName==lpfilename)
  605. return &pLoaded->m_infFile;
  606. }
  607. // The file need to be added to the list
  608. pLoaded = new CLoadedFile(lpfilename);
  609. g_LoadedFile.Add((CObject*)pLoaded);
  610. return &pLoaded->m_infFile;
  611. }
  612. PUPDATEDRESLIST CreateUpdateResList(BYTE * lpBuffer, UINT uiBufSize)
  613. {
  614. //
  615. // Walk the buffer and count how many resources we have
  616. //
  617. int iResCount = 0;
  618. int iBufSize = uiBufSize;
  619. int iResSize = 0;
  620. BYTE * pBuf = lpBuffer;
  621. while(iBufSize>0)
  622. {
  623. iResSize = 2;
  624. iResSize += strlen((LPSTR)(pBuf+iResSize))+1;
  625. iResSize += Pad4(iResSize);
  626. iResSize += 2;
  627. iResSize += strlen((LPSTR)(pBuf+iResSize))+1;
  628. iResSize += Pad4(iResSize);
  629. iResSize += 4*2;
  630. if(iResSize<=iBufSize)
  631. {
  632. iBufSize -= iResSize;
  633. pBuf = pBuf + iResSize;
  634. iResCount++;
  635. }
  636. }
  637. //
  638. // Allocate the buffer that will hold the list
  639. //
  640. if(!iResCount)
  641. return NULL;
  642. pBuf = lpBuffer;
  643. iBufSize = uiBufSize;
  644. PUPDATEDRESLIST pListHead = new UPDATEDRESLIST[iResCount];
  645. if(pListHead==NULL)
  646. AfxThrowMemoryException();
  647. memset(pListHead, 0, sizeof(UPDATEDRESLIST)*iResCount);
  648. PUPDATEDRESLIST pList = pListHead;
  649. BYTE bPad = 0;
  650. WORD wSize = 0;
  651. while(iBufSize>0) {
  652. pList->pTypeId = (WORD*)pBuf;
  653. pList->pTypeName = (BYTE*)pList->pTypeId+sizeof(WORD);
  654. // check the allignement
  655. bPad = strlen((LPSTR)pList->pTypeName)+1+sizeof(WORD);
  656. bPad += Pad4(bPad);
  657. wSize = bPad;
  658. pList->pResId = (WORD*)((BYTE*)pBuf+bPad);
  659. pList->pResName = (BYTE*)pList->pResId+sizeof(WORD);
  660. bPad = strlen((LPSTR)pList->pResName)+1+sizeof(WORD);
  661. bPad += Pad4(bPad);
  662. wSize += bPad;
  663. pList->pLang = (DWORD*)((BYTE*)pList->pResId+bPad);
  664. pList->pSize = (DWORD*)((BYTE*)pList->pLang+sizeof(DWORD));
  665. pList->pNext = (PUPDATEDRESLIST)pList+1;
  666. wSize += sizeof(DWORD)*2;
  667. pBuf = pBuf+wSize;
  668. iBufSize -= wSize;
  669. if(!iBufSize)
  670. pList->pNext = NULL;
  671. else
  672. pList++;
  673. }
  674. return pListHead;
  675. }
  676. PUPDATEDRESLIST FindId(LPCSTR pstrId, PUPDATEDRESLIST pList)
  677. {
  678. //
  679. // Note that this function assumes that the type is always right
  680. // since it is a inf file this is a fair assumption.
  681. // It could be optimized.
  682. //
  683. if(!pList)
  684. return NULL;
  685. PUPDATEDRESLIST pLast = pList;
  686. while(pList)
  687. {
  688. if(!strcmp((LPSTR)pList->pResName, pstrId)) {
  689. return pList;
  690. }
  691. pList = pList->pNext;
  692. }
  693. return NULL;
  694. }
  695. ////////////////////////////////////////////////////////////////////////////
  696. // DLL Specific code implementation
  697. ////////////////////////////////////////////////////////////////////////////
  698. ////////////////////////////////////////////////////////////////////////////
  699. // Library init
  700. static AFX_EXTENSION_MODULE rwinfDLL = { NULL, NULL };
  701. extern "C" int APIENTRY
  702. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  703. {
  704. if (dwReason == DLL_PROCESS_ATTACH)
  705. {
  706. TRACE0("RWINF.DLL Initializing!\n");
  707. AfxInitExtensionModule(rwinfDLL, hInstance);
  708. new CDynLinkLibrary(rwinfDLL);
  709. }
  710. else if (dwReason == DLL_PROCESS_DETACH)
  711. {
  712. TRACE0("RWINF.DLL Terminating!\n");
  713. // free all the loaded files
  714. int c = (int)g_LoadedFile.GetSize();
  715. CLoadedFile * pLoaded;
  716. while(c)
  717. {
  718. pLoaded = (CLoadedFile*)g_LoadedFile.GetAt(--c);
  719. delete pLoaded;
  720. }
  721. }
  722. return 1;
  723. }
  724.