---
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()獲取資源,定讀取至之前配置好的記憶體。