--- title : 12_rsctool --- # rsctool by WL, Liu Date : 2021-10-22 --- ## 壹、簡介 此部分程式碼用於取得資源,主要分為兩個主程式,一個為RetrieveResource(),用以取得資源並複製到記憶體,另一個為AllocResource(),過程中利用RetrieveResource()取得資源大小,配置一個合適的記憶體,並將資源讀取至其中。 ## 標頭檔 ```cpp= #pragma once #include <Windows.h> BOOL RetrieveResource( ULONG rcID, LPCTSTR lpType, PUCHAR pbBuffer, ULONG cbBuffer, PULONG pcbResult ); PUCHAR AllocResource( ULONG rcID, PULONG pcbResult ); ``` 構造兩函式RetrieveResource()AllocResource(),並所需引入參數,其分別功能大致如上所述。 ## 主程式 ```cpp= #include "rsctool.h" BOOL RetrieveResource( ULONG rcID, LPCTSTR lpType, PUCHAR pbBuffer, ULONG cbBuffer, PULONG pcbResult ) { ULONG cMessage = 0; HMODULE hModule = GetModuleHandle(NULL); ``` 利用函示GetModuleHandle()取得執行檔之handle。 ```cpp=13 if (!hModule) { return FALSE; } HRSRC hResource = FindResource( hModule, MAKEINTRESOURCE(rcID), lpType); ``` 取得資源,若沒有則回傳錯誤。 ```cpp=20 if (!hResource) { return FALSE; } HGLOBAL hMemory = LoadResource( hModule, hResource); ``` 載入資源,若沒有則回傳錯誤。 ```cpp=26 if (!hMemory) { return FALSE; } DWORD dwSize = SizeofResource( hModule, hResource); ``` 取得資源大小,若沒有則回傳錯誤。 ```cpp=32 if (!dwSize) { return FALSE; } if (pcbResult) { *pcbResult = dwSize; } if (pbBuffer) { if (cbBuffer < dwSize) { return FALSE; } LPVOID lpAddress = LockResource(hMemory); if (!lpAddress) { return FALSE; } CopyMemory(pbBuffer, lpAddress, dwSize); } return TRUE; } ``` * 第36行,返回第32行所得知資源大小。 * 第39行,檢查緩衝區大小是否足夠存放(用緩衝區與第32行所得知資源大小比較)。 * 第42行,鎖定並取得資源所在之記憶體,以便取用。 * 第46行,從第42行獲得之位置複製出資源。 ```cpp=51 PUCHAR AllocResource(ULONG rcID, PULONG pcbResult) { PUCHAR pbBuffer; ULONG cbBuffer; if (!RetrieveResource( rcID, RT_RCDATA, NULL, NULL, &cbBuffer)) { return NULL; } ``` 利用RetrieveResource()獲取資源之大小。 ```cpp=63 if (cbBuffer <= 0) { return NULL; } if (!(pbBuffer = (PUCHAR)HeapAlloc( GetProcessHeap(), 0, cbBuffer))) { return NULL; } ``` 配置記憶體以存放資源。 ```cpp=72 if (!RetrieveResource( rcID, RT_RCDATA, pbBuffer, cbBuffer, &cbBuffer)) { return NULL; } if (pcbResult) { *pcbResult = cbBuffer; } return pbBuffer; } ``` 利用RetrieveResource()獲取資源,定讀取至之前配置好的記憶體。