---
# System prepended metadata

title: 12_rsctool

---

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