OSDN Git Service

Change to specify explicitly code pages.
[ffftp/ffftp.git] / mbswrapper.c
index bd4a9a5..0128606 100644 (file)
-// mbswrapper.cpp
-// Copyright (C) 2011 Suguru Kawamoto
-// マルチバイト文字ワイド文字APIラッパー
-// マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする
-// 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要
-
-#define UNICODE
-#define _UNICODE
-#define _WIN32_WINNT 0x0600
-#undef _WIN32_IE
-#define _WIN32_IE 0x0400
-
-#include <tchar.h>
-#include <direct.h>
-#include <windows.h>
-#include <commctrl.h>
-#include <shlobj.h>
-#include <htmlhelp.h>
-
-#define DO_NOT_REPLACE
-#include "mbswrapper.h"
-
-// マルチバイト文字列からワイド文字列へ変換
-int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)
-{
-       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
-               return 0;
-       if(pDst)
-               return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);
-       return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);
-}
-
-// ワイド文字列からマルチバイト文字列へ変換
-int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)
-{
-       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
-               return 0;
-       if(pDst)
-               return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);
-       return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);
-}
-
-// ワイド文字列からShift_JIS文字列へ変換
-int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)
-{
-       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
-               return 0;
-       if(pDst)
-               return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);
-       return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);
-}
-
-// マルチバイト文字列バッファ終端を強制的にNULLで置換
-int TerminateStringM(LPSTR lpString, int size)
-{
-       int i;
-       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
-               return 0;
-       for(i = 0; i < size; i++)
-       {
-               if(lpString[i] == '\0')
-                       return i;
-       }
-       i--;
-       lpString[i] = '\0';
-       return i;
-}
-
-// ワイド文字列バッファ終端を強制的にNULLで置換
-int TerminateStringW(LPWSTR lpString, int size)
-{
-       int i;
-       if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)
-               return 0;
-       for(i = 0; i < size; i++)
-       {
-               if(lpString[i] == L'\0')
-                       return i;
-       }
-       i--;
-       lpString[i] = L'\0';
-       return i;
-}
-
-// Shift_JIS文字列バッファ終端を強制的にNULLで置換
-int TerminateStringA(LPSTR lpString, int size)
-{
-       int i;
-       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
-               return 0;
-       for(i = 0; i < size; i++)
-       {
-               if(lpString[i] == '\0')
-                       return i;
-       }
-       i--;
-       lpString[i] = '\0';
-       return i;
-}
-
-// NULL区切り複数マルチバイト文字列の長さを取得
-size_t GetMultiStringLengthM(LPCSTR lpString)
-{
-       size_t i;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return 0;
-       i = 0;
-       while(lpString[i] != '\0' || lpString[i + 1] != '\0')
-       {
-               i++;
-       }
-       i++;
-       return i;
-}
-
-// NULL区切り複数ワイド文字列の長さを取得
-size_t GetMultiStringLengthW(LPCWSTR lpString)
-{
-       size_t i;
-       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
-               return 0;
-       i = 0;
-       while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')
-       {
-               i++;
-       }
-       i++;
-       return i;
-}
-
-// NULL区切り複数Shift_JIS文字列の長さを取得
-size_t GetMultiStringLengthA(LPCSTR lpString)
-{
-       size_t i;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return 0;
-       i = 0;
-       while(lpString[i] != '\0' || lpString[i + 1] != '\0')
-       {
-               i++;
-       }
-       i++;
-       return i;
-}
-
-// NULL区切りマルチバイト文字列からワイド文字列へ変換
-int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)
-{
-       int i;
-       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
-               return 0;
-       if(!pDst)
-               return GetMultiStringLengthM(pSrc);
-       i = 0;
-       while(*pSrc != '\0')
-       {
-               i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);
-               pSrc += strlen(pSrc) + 1;
-       }
-       pDst[i] = L'\0';
-       return i;
-}
-
-// NULL区切りワイド文字列からマルチバイト文字列へ変換
-int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
-{
-       int i;
-       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
-               return 0;
-       if(!pDst)
-               return GetMultiStringLengthW(pSrc);
-       i = 0;
-       while(*pSrc != L'\0')
-       {
-               i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
-               pSrc += wcslen(pSrc) + 1;
-       }
-       pDst[i] = '\0';
-       return i;
-}
-
-// NULL区切りワイド文字列からShift_JIS文字列へ変換
-int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
-{
-       int i;
-       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
-               return 0;
-       if(!pDst)
-               return GetMultiStringLengthW(pSrc);
-       i = 0;
-       while(*pSrc != L'\0')
-       {
-               i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
-               pSrc += wcslen(pSrc) + 1;
-       }
-       pDst[i] = '\0';
-       return i;
-}
-
-// マルチバイト文字列用のメモリを確保
-char* AllocateStringM(int size)
-{
-       char* p;
-       // 0が指定される場合があるため1文字分追加
-       p = (char*)malloc(sizeof(char) * (size + 1));
-       // 念のため先頭にNULL文字を代入
-       if(p)
-               *p = '\0';
-       return p;
-}
-
-// ワイド文字列用のメモリを確保
-wchar_t* AllocateStringW(int size)
-{
-       wchar_t* p;
-       // 0が指定される場合があるため1文字分追加
-       p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));
-       // 念のため先頭にNULL文字を代入
-       if(p)
-               *p = L'\0';
-       return p;
-}
-
-// Shift_JIS文字列用のメモリを確保
-char* AllocateStringA(int size)
-{
-       char* p;
-       // 0が指定される場合があるため1文字分追加
-       p = (char*)malloc(sizeof(char) * (size + 1));
-       // 念のため先頭にNULL文字を代入
-       if(p)
-               *p = '\0';
-       return p;
-}
-
-// メモリを確保してマルチバイト文字列からワイド文字列へ変換
-wchar_t* DuplicateMtoW(LPCSTR lpString, int c)
-{
-       wchar_t* p;
-       int i;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return (wchar_t*)lpString;
-       if(c < 0)
-               c = strlen(lpString);
-       p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);
-       if(p)
-       {
-               i = MtoW(p, 65535, lpString, c);
-               p[i] = L'\0';
-       }
-       return p;
-}
-
-// 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換
-wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)
-{
-       wchar_t* p;
-       int i;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return (wchar_t*)lpString;
-       if(c < 0)
-               c = strlen(lpString);
-       p = AllocateStringW(size);
-       if(p)
-       {
-               i = MtoW(p, size, lpString, c);
-               p[i] = L'\0';
-       }
-       return p;
-}
-
-// メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換
-wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)
-{
-       int count;
-       wchar_t* p;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return (wchar_t*)lpString;
-       count = GetMultiStringLengthM(lpString) + 1;
-       p = AllocateStringW(count);
-       if(p)
-               MtoW(p, count, lpString, count);
-       return p;
-}
-
-// 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換
-wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)
-{
-       int count;
-       wchar_t* p;
-       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
-               return (wchar_t*)lpString;
-       count = GetMultiStringLengthM(lpString) + 1;
-       p = AllocateStringW(size);
-       if(p)
-       {
-               MtoW(p, size, lpString, count);
-               p[size - 2] = L'\0';
-               p[size - 1] = L'\0';
-       }
-       return p;
-}
-
-// メモリを確保してワイド文字列からマルチバイト文字列へ変換
-char* DuplicateWtoM(LPCWSTR lpString, int c)
-{
-       char* p;
-       int i;
-       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
-               return (char*)lpString;
-       if(c < 0)
-               c = wcslen(lpString);
-       p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);
-       if(p)
-       {
-               i = WtoM(p, 65535, lpString, c);
-               p[i] = L'\0';
-       }
-       return p;
-}
-
-// メモリを確保してワイド文字列からShift_JIS文字列へ変換
-char* DuplicateWtoA(LPCWSTR lpString, int c)
-{
-       char* p;
-       int i;
-       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
-               return (char*)lpString;
-       if(c < 0)
-               c = wcslen(lpString);
-       p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);
-       if(p)
-       {
-               i = WtoA(p, 65535, lpString, c);
-               p[i] = L'\0';
-       }
-       return p;
-}
-
-// 文字列用に確保したメモリを開放
-void FreeDuplicatedString(void* p)
-{
-       if(p < (void*)0x00010000 || p == (void*)~0)
-               return;
-       free(p);
-}
-
-// 以下ラッパー
-// 戻り値バッファ r
-// ワイド文字バッファ pw%d
-// マルチバイト文字バッファ pm%d
-// 引数バッファ a%d
-
-#define START_ROUTINE                                  do{
-#define END_ROUTINE                                            }while(0);end_of_routine:
-#define QUIT_ROUTINE                                   goto end_of_routine;
-
-HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
-{
-       HANDLE r = INVALID_HANDLE_VALUE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpFileName, -1);
-       r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
-{
-       int r = IDOK;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpText, -1);
-       pw1 = DuplicateMtoW(lpCaption, -1);
-       r = MessageBoxW(hWnd, pw0, pw1, uType);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
-{
-       HANDLE r = INVALID_HANDLE_VALUE;
-       wchar_t* pw0 = NULL;
-       WIN32_FIND_DATAW a0;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpFileName, -1);
-       r = FindFirstFileW(pw0, &a0);
-       if(r != INVALID_HANDLE_VALUE)
-       {
-               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
-               lpFindFileData->ftCreationTime = a0.ftCreationTime;
-               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
-               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
-               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
-               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
-               lpFindFileData->dwReserved0 = a0.dwReserved0;
-               lpFindFileData->dwReserved1 = a0.dwReserved1;
-               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
-               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
-{
-       BOOL r = FALSE;
-       WIN32_FIND_DATAW a0;
-START_ROUTINE
-       r = FindNextFileW(hFindFile, &a0);
-       if(r)
-       {
-               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
-               lpFindFileData->ftCreationTime = a0.ftCreationTime;
-               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
-               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
-               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
-               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
-               lpFindFileData->dwReserved0 = a0.dwReserved0;
-               lpFindFileData->dwReserved1 = a0.dwReserved1;
-               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
-               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
-       }
-END_ROUTINE
-       return r;
-}
-
-DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)
-{
-       DWORD r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = AllocateStringW(nBufferLength * 4);
-       GetLogicalDriveStringsW(nBufferLength * 4, pw0);
-       WtoMMultiString(lpBuffer, nBufferLength, pw0);
-       r = TerminateStringM(lpBuffer, nBufferLength);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)
-{
-       ATOM r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       r = RegisterClassExA(v0);
-END_ROUTINE
-       return r;
-}
-
-HWND CreateWindowExM(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
-{
-       HWND r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpClassName, -1);
-       pw1 = DuplicateMtoW(lpWindowName, -1);
-       r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-LONG GetWindowLongM(HWND hWnd, int nIndex)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       if(IsWindowUnicode(hWnd))
-               r = GetWindowLongW(hWnd, nIndex);
-       else
-               r = GetWindowLongA(hWnd, nIndex);
-END_ROUTINE
-       return r;
-}
-
-LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       if(IsWindowUnicode(hWnd))
-               r = SetWindowLongW(hWnd, nIndex, dwNewLong);
-       else
-               r = SetWindowLongA(hWnd, nIndex, dwNewLong);
-END_ROUTINE
-       return r;
-}
-
-LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       if(IsWindowUnicode(hWnd))
-               r = DefWindowProcW(hWnd, Msg, wParam, lParam);
-       else
-               r = DefWindowProcA(hWnd, Msg, wParam, lParam);
-END_ROUTINE
-       return r;
-}
-
-LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       if(IsWindowUnicode(hWnd))
-               r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
-       else
-               r = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);
-END_ROUTINE
-       return r;
-}
-
-LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
-       LRESULT r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       int Size;
-       LVITEMA* pmLVItem;
-       LVITEMW wLVItem;
-       LVFINDINFOA* pmLVFindInfo;
-       LVFINDINFOW wLVFindInfo;
-       LVCOLUMNA* pmLVColumn;
-       LVCOLUMNW wLVColumn;
-       wchar_t ClassName[MAX_PATH];
-START_ROUTINE
-       switch(Msg)
-       {
-       case WM_SETTEXT:
-               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-               r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);
-               break;
-       case WM_GETTEXT:
-               pw0 = AllocateStringW(wParam * 4);
-               SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);
-               WtoM((LPSTR)lParam, wParam, pw0, -1);
-               r = TerminateStringM((LPSTR)lParam, wParam);
-               break;
-       case WM_GETTEXTLENGTH:
-               Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1;
-               pw0 = AllocateStringW(Size);
-               SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);
-               r = WtoM(NULL, 0, pw0, -1) - 1;
-               break;
-       default:
-               GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));
-               if(_wcsicmp(ClassName, WC_EDITW) == 0)
-               {
-                       switch(Msg)
-                       {
-                       case EM_REPLACESEL:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);
-                               break;
-                       default:
-                               r = SendMessageW(hWnd, Msg, wParam, lParam);
-                               break;
-                       }
-               }
-               else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)
-               {
-                       switch(Msg)
-                       {
-                       case CB_ADDSTRING:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);
-                               break;
-                       case CB_GETLBTEXT:
-                               Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
-                               pw0 = AllocateStringW(Size);
-                               SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);
-                               // バッファ長不明のためオーバーランの可能性あり
-                               WtoM((LPSTR)lParam, Size * 4, pw0, -1);
-                               r = TerminateStringM((LPSTR)lParam, Size * 4);
-                               break;
-                       case CB_GETLBTEXTLEN:
-                               Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;
-                               pw0 = AllocateStringW(Size);
-                               SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
-                               r = WtoM(NULL, 0, pw0, -1) - 1;
-                               break;
-                       case CB_INSERTSTRING:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);
-                               break;
-                       case CB_FINDSTRINGEXACT:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);
-                               break;
-                       default:
-                               r = SendMessageW(hWnd, Msg, wParam, lParam);
-                               break;
-                       }
-               }
-               else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)
-               {
-                       switch(Msg)
-                       {
-                       case LB_ADDSTRING:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);
-                               break;
-                       case LB_INSERTSTRING:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);
-                               break;
-                       case LB_GETTEXT:
-                               Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
-                               pw0 = AllocateStringW(Size);
-                               SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);
-                               // バッファ長不明のためオーバーランの可能性あり
-                               WtoM((LPSTR)lParam, Size * 4, pw0, -1);
-                               r = TerminateStringM((LPSTR)lParam, Size * 4);
-                               break;
-                       case LB_GETTEXTLEN:
-                               Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;
-                               pw0 = AllocateStringW(Size);
-                               SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);
-                               r = WtoM(NULL, 0, pw0, -1) - 1;
-                               break;
-                       default:
-                               r = SendMessageW(hWnd, Msg, wParam, lParam);
-                               break;
-                       }
-               }
-               else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)
-               {
-                       switch(Msg)
-                       {
-                       case LVM_GETITEMA:
-                               pmLVItem = (LVITEMA*)lParam;
-                               wLVItem.mask = pmLVItem->mask;
-                               wLVItem.iItem = pmLVItem->iItem;
-                               wLVItem.iSubItem = pmLVItem->iSubItem;
-                               wLVItem.state = pmLVItem->state;
-                               wLVItem.stateMask = pmLVItem->stateMask;
-                               if(pmLVItem->mask & LVIF_TEXT)
-                               {
-                                       Size = pmLVItem->cchTextMax * 4;
-                                       pw0 = AllocateStringW(Size);
-                                       wLVItem.pszText = pw0;
-                                       wLVItem.cchTextMax = Size;
-                               }
-                               wLVItem.iImage = pmLVItem->iImage;
-                               wLVItem.lParam = pmLVItem->lParam;
-                               wLVItem.iIndent = pmLVItem->iIndent;
-                               r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);
-                               pmLVItem->mask = wLVItem.mask;
-                               pmLVItem->iItem = wLVItem.iItem;
-                               pmLVItem->iSubItem = wLVItem.iSubItem;
-                               pmLVItem->state = wLVItem.state;
-                               pmLVItem->stateMask = wLVItem.stateMask;
-                               if(pmLVItem->mask & LVIF_TEXT)
-                               {
-                                       WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
-                                       TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
-                               }
-                               pmLVItem->iImage = wLVItem.iImage;
-                               pmLVItem->lParam = wLVItem.lParam;
-                               pmLVItem->iIndent = wLVItem.iIndent;
-                               break;
-                       case LVM_SETITEMA:
-                               pmLVItem = (LVITEMA*)lParam;
-                               wLVItem.mask = pmLVItem->mask;
-                               wLVItem.iItem = pmLVItem->iItem;
-                               wLVItem.iSubItem = pmLVItem->iSubItem;
-                               wLVItem.state = pmLVItem->state;
-                               wLVItem.stateMask = pmLVItem->stateMask;
-                               if(pmLVItem->mask & LVIF_TEXT)
-                               {
-                                       pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
-                                       wLVItem.pszText = pw0;
-                                       // TODO: cchTextMaxの確認
-                                       wLVItem.cchTextMax = pmLVItem->cchTextMax;
-                               }
-                               wLVItem.iImage = pmLVItem->iImage;
-                               wLVItem.lParam = pmLVItem->lParam;
-                               wLVItem.iIndent = pmLVItem->iIndent;
-                               r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);
-                               break;
-                       case LVM_INSERTITEMA:
-                               pmLVItem = (LVITEMA*)lParam;
-                               wLVItem.mask = pmLVItem->mask;
-                               wLVItem.iItem = pmLVItem->iItem;
-                               wLVItem.iSubItem = pmLVItem->iSubItem;
-                               wLVItem.state = pmLVItem->state;
-                               wLVItem.stateMask = pmLVItem->stateMask;
-                               if(pmLVItem->mask & LVIF_TEXT)
-                               {
-                                       pw0 = DuplicateMtoW(pmLVItem->pszText, -1);
-                                       wLVItem.pszText = pw0;
-                                       // TODO: cchTextMaxの確認
-                                       wLVItem.cchTextMax = pmLVItem->cchTextMax;
-                               }
-                               wLVItem.iImage = pmLVItem->iImage;
-                               wLVItem.lParam = pmLVItem->lParam;
-                               wLVItem.iIndent = pmLVItem->iIndent;
-                               r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);
-                               break;
-                       case LVM_FINDITEMA:
-                               pmLVFindInfo = (LVFINDINFOA*)lParam;
-                               wLVFindInfo.flags = pmLVFindInfo->flags;
-                               if(pmLVFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))
-                               {
-                                       pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);
-                                       wLVFindInfo.psz = pw0;
-                               }
-                               wLVFindInfo.lParam = pmLVFindInfo->lParam;
-                               wLVFindInfo.pt = pmLVFindInfo->pt;
-                               wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;
-                               r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);
-                               break;
-                       case LVM_GETCOLUMNA:
-                               pmLVColumn = (LVCOLUMNA*)lParam;
-                               wLVColumn.mask = pmLVColumn->mask;
-                               wLVColumn.fmt = pmLVColumn->fmt;
-                               wLVColumn.cx = pmLVColumn->cx;
-                               Size = pmLVColumn->cchTextMax * 4;
-                               if(pmLVColumn->mask & LVCF_TEXT)
-                               {
-                                       pw0 = AllocateStringW(Size);
-                                       wLVColumn.pszText = pw0;
-                                       wLVColumn.cchTextMax = Size;
-                               }
-                               wLVColumn.iSubItem = pmLVColumn->iSubItem;
-                               wLVColumn.iImage = pmLVColumn->iImage;
-                               wLVColumn.iOrder = pmLVColumn->iOrder;
-                               r = SendMessageW(hWnd, LVM_GETCOLUMNW, wParam, (LPARAM)&wLVColumn);
-                               pmLVColumn->mask = wLVColumn.mask;
-                               pmLVColumn->fmt = wLVColumn.fmt;
-                               pmLVColumn->cx = wLVColumn.cx;
-                               if(pmLVColumn->mask & LVCF_TEXT)
-                               {
-                                       WtoM(pmLVColumn->pszText, pmLVColumn->cchTextMax, wLVColumn.pszText, -1);
-                                       TerminateStringM(pmLVColumn->pszText, pmLVColumn->cchTextMax);
-                               }
-                               pmLVColumn->iSubItem = wLVColumn.iSubItem;
-                               pmLVColumn->iImage = wLVColumn.iImage;
-                               pmLVColumn->iOrder = wLVColumn.iOrder;
-                               break;
-                       case LVM_INSERTCOLUMNA:
-                               pmLVColumn = (LVCOLUMNA*)lParam;
-                               wLVColumn.mask = pmLVColumn->mask;
-                               wLVColumn.fmt = pmLVColumn->fmt;
-                               wLVColumn.cx = pmLVColumn->cx;
-                               if(pmLVColumn->mask & LVCF_TEXT)
-                               {
-                                       pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);
-                                       wLVColumn.pszText = pw0;
-                                       // TODO: cchTextMaxの確認
-                                       wLVColumn.cchTextMax = pmLVColumn->cchTextMax;
-                               }
-                               wLVColumn.iSubItem = pmLVColumn->iSubItem;
-                               wLVColumn.iImage = pmLVColumn->iImage;
-                               wLVColumn.iOrder = pmLVColumn->iOrder;
-                               r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);
-                               break;
-                       case LVM_GETITEMTEXTA:
-                               pmLVItem = (LVITEMA*)lParam;
-                               wLVItem.mask = pmLVItem->mask;
-                               wLVItem.iItem = pmLVItem->iItem;
-                               wLVItem.iSubItem = pmLVItem->iSubItem;
-                               wLVItem.state = pmLVItem->state;
-                               wLVItem.stateMask = pmLVItem->stateMask;
-                               Size = pmLVItem->cchTextMax * 4;
-                               pw0 = AllocateStringW(Size);
-                               wLVItem.pszText = pw0;
-                               wLVItem.cchTextMax = Size;
-                               wLVItem.iImage = pmLVItem->iImage;
-                               wLVItem.lParam = pmLVItem->lParam;
-                               wLVItem.iIndent = pmLVItem->iIndent;
-                               r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);
-                               pmLVItem->mask = wLVItem.mask;
-                               pmLVItem->iItem = wLVItem.iItem;
-                               pmLVItem->iSubItem = wLVItem.iSubItem;
-                               pmLVItem->state = wLVItem.state;
-                               pmLVItem->stateMask = wLVItem.stateMask;
-                               WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);
-                               TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);
-                               pmLVItem->iImage = wLVItem.iImage;
-                               pmLVItem->lParam = wLVItem.lParam;
-                               pmLVItem->iIndent = wLVItem.iIndent;
-                               break;
-                       default:
-                               r = SendMessageW(hWnd, Msg, wParam, lParam);
-                               break;
-                       }
-               }
-               else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)
-               {
-                       switch(Msg)
-                       {
-                       case SB_SETTEXTA:
-                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);
-                               r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);
-                               break;
-                       default:
-                               r = SendMessageW(hWnd, Msg, wParam, lParam);
-                               break;
-                       }
-               }
-               else
-                       r = SendMessageW(hWnd, Msg, wParam, lParam);
-               break;
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-LRESULT DefDlgProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       // WNDPROCがShift_JIS用であるため
-       if(IsWindowUnicode(hWnd))
-               r = DefDlgProcW(hWnd, Msg, wParam, lParam);
-       else
-               r = DefDlgProcA(hWnd, Msg, wParam, lParam);
-END_ROUTINE
-       return r;
-}
-
-LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)
-{
-       LRESULT r = 0;
-START_ROUTINE
-       r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);
-END_ROUTINE
-       return r;
-}
-
-BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpString, -1);
-       r = SetWindowTextW(hWnd, pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)
-{
-       UINT r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       if(iFile == (UINT)-1)
-               r = DragQueryFileW(hDrop, iFile, (LPWSTR)lpszFile, cch);
-       else
-       {
-               pw0 = AllocateStringW(cch * 4);
-               DragQueryFileW(hDrop, iFile, pw0, cch * 4);
-               WtoM(lpszFile, cch, pw0, -1);
-               r = TerminateStringM(lpszFile, cch);
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)
-{
-       DWORD r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = AllocateStringW(nBufferLength * 4);
-       GetCurrentDirectoryW(nBufferLength * 4, pw0);
-       WtoM(lpBuffer, nBufferLength, pw0, -1);
-       r = TerminateStringM(lpBuffer, nBufferLength);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL SetCurrentDirectoryM(LPCSTR lpPathName)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpPathName, -1);
-       r = SetCurrentDirectoryW(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL SetDllDirectoryM(LPCSTR lpPathName)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpPathName, -1);
-       r = SetDllDirectoryW(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)
-{
-       DWORD r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = AllocateStringW(nBufferLength * 4);
-       GetTempPathW(nBufferLength * 4, pw0);
-       WtoM(lpBuffer, nBufferLength, pw0, -1);
-       r = TerminateStringM(lpBuffer, nBufferLength);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-DWORD GetFileAttributesM(LPCSTR lpFileName)
-{
-       DWORD r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpFileName, -1);
-       r = GetFileAttributesW(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)
-{
-       DWORD r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = AllocateStringW(nSize * 4);
-       GetModuleFileNameW(hModule, pw0, nSize * 4);
-       WtoM(lpFilename, nSize, pw0, -1);
-       r = TerminateStringM(lpFilename, nSize);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
-{
-       LSTATUS r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpSubKey, -1);
-       r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)
-{
-       LSTATUS r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpSubKey, -1);
-       pw1 = DuplicateMtoW(lpClass, -1);
-       r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)
-{
-       LSTATUS r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpValueName, -1);
-       r = RegDeleteValueW(hKey, pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
-{
-       LSTATUS r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       DWORD dwType;
-       DWORD wcbData;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpValueName, -1);
-       if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)
-       {
-               switch(dwType)
-               {
-               case REG_SZ:
-               case REG_EXPAND_SZ:
-               case REG_MULTI_SZ:
-                       if(lpcbData)
-                       {
-                               pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);
-                               wcbData = *lpcbData / sizeof(char) * 4;
-                               r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);
-                               if(lpData)
-                                       *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));
-                               else
-                                       *lpcbData = sizeof(char) * WtoM(NULL, 0, pw1, wcbData / sizeof(wchar_t));
-                       }
-                       break;
-               default:
-                       r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
-                       break;
-               }
-       }
-       else
-               r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)
-{
-       LSTATUS r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       DWORD wcbData;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpValueName, -1);
-       switch(dwType)
-       {
-       case REG_SZ:
-       case REG_EXPAND_SZ:
-       case REG_MULTI_SZ:
-               wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));
-               pw1 = AllocateStringW(wcbData);
-               MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));
-               wcbData = sizeof(wchar_t) * wcbData;
-               lpData = (BYTE*)pw1;
-               cbData = wcbData;
-               break;
-       }
-       r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpString, c);
-       r = TextOutW(hdc, x, y, pw0, wcslen(pw0));
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpString, c);
-       r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)
-{
-       INT_PTR r = 0;
-       PROPSHEETHEADERW a0;
-       PROPSHEETPAGEW* pwPage;
-       UINT i;
-START_ROUTINE
-       a0.dwSize = sizeof(PROPSHEETHEADERW);
-       a0.dwFlags = v0->dwFlags;
-       a0.hwndParent = v0->hwndParent;
-       a0.hInstance = v0->hInstance;
-       if(v0->dwFlags & PSH_USEICONID)
-               a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);
-       else
-               a0.hIcon = v0->hIcon;
-       a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);
-       a0.nPages = v0->nPages;
-       a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);
-       if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))
-       {
-               for(i = 0; i < v0->nPages; i++)
-               {
-                       pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);
-                       pwPage[i].dwFlags = v0->ppsp[i].dwFlags;
-                       pwPage[i].hInstance = v0->ppsp[i].hInstance;
-                       pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);
-                       if(v0->ppsp[i].dwFlags & PSP_USEICONID)
-                               pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);
-                       else
-                               pwPage[i].hIcon = v0->ppsp[i].hIcon;
-                       if(v0->ppsp[i].dwFlags & PSP_USETITLE)
-                               pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);
-                       pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;
-                       pwPage[i].lParam = v0->ppsp[i].lParam;
-                       // TODO: pfnCallback
-                       pwPage[i].pfnCallback = v0->ppsp[i].pfnCallback;
-                       pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;
-//                     pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);
-//                     pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);
-                       pwPage[i].hActCtx = v0->ppsp[i].hActCtx;
-//                     pwPage[i].pszbmHeader = DuplicateMtoW(v0->ppsp[i].pszbmHeader, -1);
-               }
-       }
-       else
-               pwPage = NULL;
-       a0.ppsp = pwPage;
-       a0.pfnCallback = v0->pfnCallback;
-       r = PropertySheetW(&a0);
-       if(a0.dwFlags & PSH_USEICONID)
-               FreeDuplicatedString(a0.pszIcon);
-       FreeDuplicatedString(a0.pszCaption);
-       FreeDuplicatedString(a0.pStartPage);
-       if(pwPage)
-       {
-               for(i = 0; i < v0->nPages; i++)
-               {
-                       FreeDuplicatedString(pwPage[i].pszTemplate);
-                       if(pwPage[i].dwFlags & PSP_USEICONID)
-                               FreeDuplicatedString(pwPage[i].pszIcon);
-                       if(pwPage[i].dwFlags & PSP_USETITLE)
-                               FreeDuplicatedString(pwPage[i].pszTitle);
-//                     FreeDuplicatedString(pwPage[i].pszHeaderTitle);
-//                     FreeDuplicatedString(pwPage[i].pszHeaderSubTitle);
-//                     FreeDuplicatedString(pwPage[i].pszbmHeader);
-               }
-               free(pwPage);
-       }
-END_ROUTINE
-       return r;
-}
-
-BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       wchar_t* pw3 = NULL;
-       wchar_t* pw4 = NULL;
-       wchar_t* pw5 = NULL;
-       wchar_t* pw6 = NULL;
-       wchar_t* pw7 = NULL;
-       wchar_t* pw8 = NULL;
-       wchar_t* pw9 = NULL;
-       OPENFILENAMEW wofn;
-START_ROUTINE
-       wofn.lStructSize = sizeof(OPENFILENAMEW);
-       wofn.hwndOwner = v0->hwndOwner;
-       wofn.hInstance = v0->hInstance;
-       pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
-       wofn.lpstrFilter = pw0;
-       pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
-       wofn.lpstrCustomFilter = pw1;
-       wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
-       wofn.nFilterIndex = v0->nFilterIndex;
-       pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
-       wofn.lpstrFile = pw2;
-       wofn.nMaxFile = v0->nMaxFile * 4;
-       pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
-       wofn.lpstrFileTitle = pw3;
-       wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
-       pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
-       wofn.lpstrInitialDir = pw4;
-       pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
-       wofn.lpstrTitle = pw5;
-       wofn.Flags = v0->Flags;
-       wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
-       wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
-       pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
-       wofn.lpstrDefExt = pw6;
-       wofn.lCustData = v0->lCustData;
-       wofn.lpfnHook = v0->lpfnHook;
-       wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
-       wofn.pvReserved = v0->pvReserved;
-       wofn.FlagsEx = v0->FlagsEx;
-       r = GetOpenFileNameW(&wofn);
-       WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
-       TerminateStringM(v0->lpstrFile, v0->nMaxFile);
-       v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
-       v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       FreeDuplicatedString(pw3);
-       FreeDuplicatedString(pw4);
-       FreeDuplicatedString(pw5);
-       FreeDuplicatedString(pw6);
-       return r;
-}
-
-BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       wchar_t* pw3 = NULL;
-       wchar_t* pw4 = NULL;
-       wchar_t* pw5 = NULL;
-       wchar_t* pw6 = NULL;
-       wchar_t* pw7 = NULL;
-       wchar_t* pw8 = NULL;
-       wchar_t* pw9 = NULL;
-       OPENFILENAMEW wofn;
-START_ROUTINE
-       wofn.lStructSize = sizeof(OPENFILENAMEW);
-       wofn.hwndOwner = v0->hwndOwner;
-       wofn.hInstance = v0->hInstance;
-       pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);
-       wofn.lpstrFilter = pw0;
-       pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);
-       wofn.lpstrCustomFilter = pw1;
-       wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;
-       wofn.nFilterIndex = v0->nFilterIndex;
-       pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);
-       wofn.lpstrFile = pw2;
-       wofn.nMaxFile = v0->nMaxFile * 4;
-       pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);
-       wofn.lpstrFileTitle = pw3;
-       wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;
-       pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);
-       wofn.lpstrInitialDir = pw4;
-       pw5 = DuplicateMtoW(v0->lpstrTitle, -1);
-       wofn.lpstrTitle = pw5;
-       wofn.Flags = v0->Flags;
-       wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);
-       wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);
-       pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);
-       wofn.lpstrDefExt = pw6;
-       wofn.lCustData = v0->lCustData;
-       wofn.lpfnHook = v0->lpfnHook;
-       wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
-       wofn.pvReserved = v0->pvReserved;
-       wofn.FlagsEx = v0->FlagsEx;
-       r = GetSaveFileNameW(&wofn);
-       WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);
-       TerminateStringM(v0->lpstrFile, v0->nMaxFile);
-       v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);
-       v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       FreeDuplicatedString(pw3);
-       FreeDuplicatedString(pw4);
-       FreeDuplicatedString(pw5);
-       FreeDuplicatedString(pw6);
-       return r;
-}
-
-HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)
-{
-       HWND r = NULL;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(pszFile, -1);
-       r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL CreateProcessM(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       wchar_t* pw3 = NULL;
-       wchar_t* pw4 = NULL;
-       wchar_t* pw5 = NULL;
-       STARTUPINFOW wStartupInfo;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpApplicationName, -1);
-       pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);
-       pw2 = DuplicateMtoW(lpCurrentDirectory, -1);
-       wStartupInfo.cb = sizeof(LPSTARTUPINFOW);
-       pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);
-       wStartupInfo.lpReserved = pw3;
-       pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);
-       wStartupInfo.lpDesktop = pw4;
-       pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);
-       wStartupInfo.lpTitle = pw5;
-       wStartupInfo.dwX = lpStartupInfo->dwX;
-       wStartupInfo.dwY = lpStartupInfo->dwY;
-       wStartupInfo.dwXSize = lpStartupInfo->dwXSize;
-       wStartupInfo.dwYSize = lpStartupInfo->dwYSize;
-       wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;
-       wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;
-       wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;
-       wStartupInfo.dwFlags = lpStartupInfo->dwFlags;
-       wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;
-       wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;
-       wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;
-       wStartupInfo.hStdInput = lpStartupInfo->hStdInput;
-       wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;
-       wStartupInfo.hStdError = lpStartupInfo->hStdError;
-       r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);
-       WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       FreeDuplicatedString(pw3);
-       FreeDuplicatedString(pw4);
-       FreeDuplicatedString(pw5);
-       return r;
-}
-
-HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
-{
-       HINSTANCE r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       wchar_t* pw3 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpFile, -1);
-       pw1 = DuplicateMtoW(lpDirectory, -1);
-       pw2 = AllocateStringW(MAX_PATH * 4);
-       r = FindExecutableW(pw0, pw1, pw2);
-       // バッファ長不明のためオーバーランの可能性あり
-       WtoM(lpResult, MAX_PATH, pw2, -1);
-       TerminateStringM(lpResult, MAX_PATH);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       FreeDuplicatedString(pw3);
-       return r;
-}
-
-HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)
-{
-       HINSTANCE r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       wchar_t* pw3 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpOperation, -1);
-       pw1 = DuplicateMtoW(lpFile, -1);
-       pw2 = DuplicateMtoW(lpParameters, -1);
-       pw3 = DuplicateMtoW(lpDirectory, -1);
-       r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       FreeDuplicatedString(pw3);
-       return r;
-}
-
-PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)
-{
-       PIDLIST_ABSOLUTE r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       BROWSEINFOW wbi;
-START_ROUTINE
-       wbi.hwndOwner = lpbi->hwndOwner;
-       wbi.pidlRoot = lpbi->pidlRoot;
-       pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);
-       wbi.pszDisplayName = pw0;
-       pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);
-       wbi.lpszTitle = pw1;
-       wbi.ulFlags = lpbi->ulFlags;
-       // TODO: lpfn
-       wbi.lpfn = lpbi->lpfn;
-       wbi.lParam = lpbi->lParam;
-       wbi.iImage = lpbi->iImage;
-       r = SHBrowseForFolderW(&wbi);
-       // バッファ長不明のためオーバーランの可能性あり
-       WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);
-       lpbi->iImage = wbi.iImage;
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = AllocateStringW(MAX_PATH * 4);
-       r = SHGetPathFromIDListW(pidl, pw0);
-       // バッファ長不明のためオーバーランの可能性あり
-       WtoM(pszPath, MAX_PATH, pw0, -1);
-       TerminateStringM(pszPath, MAX_PATH);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* pw2 = NULL;
-       SHFILEOPSTRUCTW wFileOp;
-START_ROUTINE
-       wFileOp.hwnd = lpFileOp->hwnd;
-       wFileOp.wFunc = lpFileOp->wFunc;
-       pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);
-       wFileOp.pFrom = pw0;
-       pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);
-       wFileOp.pTo = pw1;
-       wFileOp.fFlags = lpFileOp->fFlags;
-       wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;
-       wFileOp.hNameMappings = lpFileOp->hNameMappings;
-       pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);
-       r = SHFileOperationW(&wFileOp);
-       lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       FreeDuplicatedString(pw2);
-       return r;
-}
-
-BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       if(uFlags & (MF_BITMAP | MF_OWNERDRAW))
-               r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);
-       else
-       {
-               pw0 = DuplicateMtoW(lpNewItem, -1);
-               r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       MENUITEMINFOW wmii;
-START_ROUTINE
-       wmii.cbSize = sizeof(MENUITEMINFOW);
-       wmii.fMask = lpmii->fMask;
-       wmii.fType = lpmii->fType;
-       wmii.fState = lpmii->fState;
-       wmii.wID = lpmii->wID;
-       wmii.hSubMenu = lpmii->hSubMenu;
-       wmii.hbmpChecked = lpmii->hbmpChecked;
-       wmii.hbmpUnchecked = lpmii->hbmpUnchecked;
-       wmii.dwItemData = lpmii->dwItemData;
-       pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);
-       wmii.dwTypeData = pw0;
-       wmii.cch = lpmii->cch * 4;
-       r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);
-       lpmii->fType = wmii.fType;
-       lpmii->fState = wmii.fState;
-       lpmii->wID = wmii.wID;
-       lpmii->hSubMenu = wmii.hSubMenu;
-       lpmii->hbmpChecked = wmii.hbmpChecked;
-       lpmii->hbmpUnchecked = wmii.hbmpUnchecked;
-       lpmii->dwItemData = wmii.dwItemData;
-       WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);
-       TerminateStringM(lpmii->dwTypeData, lpmii->cch);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)
-{
-       HFONT r = NULL;
-       LOGFONTW wlf;
-START_ROUTINE
-       wlf.lfHeight = lplf->lfHeight;
-       wlf.lfWidth = lplf->lfWidth;
-       wlf.lfEscapement = lplf->lfEscapement;
-       wlf.lfOrientation = lplf->lfOrientation;
-       wlf.lfWeight = lplf->lfWeight;
-       wlf.lfItalic = lplf->lfItalic;
-       wlf.lfUnderline = lplf->lfUnderline;
-       wlf.lfStrikeOut = lplf->lfStrikeOut;
-       wlf.lfCharSet = lplf->lfCharSet;
-       wlf.lfOutPrecision = lplf->lfOutPrecision;
-       wlf.lfClipPrecision = lplf->lfClipPrecision;
-       wlf.lfQuality = lplf->lfQuality;
-       wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;
-       MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);
-       TerminateStringW(wlf.lfFaceName, LF_FACESIZE);
-       r = CreateFontIndirect(&wlf);
-END_ROUTINE
-       return r;
-}
-
-BOOL ChooseFontM(LPCHOOSEFONTA v0)
-{
-       BOOL r = FALSE;
-       wchar_t* pw0 = NULL;
-       CHOOSEFONTW a0;
-       LOGFONTW* pwlf;
-START_ROUTINE
-       a0.lStructSize = sizeof(CHOOSEFONTW);
-       a0.hwndOwner = v0->hwndOwner;
-       a0.hDC = v0->hDC;
-       if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))
-       {
-               pwlf->lfHeight = v0->lpLogFont->lfHeight;
-               pwlf->lfWidth = v0->lpLogFont->lfWidth;
-               pwlf->lfEscapement = v0->lpLogFont->lfEscapement;
-               pwlf->lfOrientation = v0->lpLogFont->lfOrientation;
-               pwlf->lfWeight = v0->lpLogFont->lfWeight;
-               pwlf->lfItalic = v0->lpLogFont->lfItalic;
-               pwlf->lfUnderline = v0->lpLogFont->lfUnderline;
-               pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;
-               pwlf->lfCharSet = v0->lpLogFont->lfCharSet;
-               pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;
-               pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;
-               pwlf->lfQuality = v0->lpLogFont->lfQuality;
-               pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;
-               MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);
-               TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);
-       }
-       else
-               pwlf = NULL;
-       a0.lpLogFont = pwlf;
-       a0.iPointSize = v0->iPointSize;
-       a0.Flags = v0->Flags;
-       a0.rgbColors = v0->rgbColors;
-       a0.lCustData = v0->lCustData;
-       a0.lpfnHook = v0->lpfnHook;
-       a0.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);
-       a0.hInstance = v0->hInstance;
-       a0.lpszStyle = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);
-       a0.nFontType = v0->nFontType;
-       a0.nSizeMin = v0->nSizeMin;
-       a0.nSizeMax = v0->nSizeMax;
-       r = ChooseFontW(&a0);
-       if(v0->lpLogFont)
-       {
-               v0->lpLogFont->lfHeight = pwlf->lfHeight;
-               v0->lpLogFont->lfWidth = pwlf->lfWidth;
-               v0->lpLogFont->lfEscapement = pwlf->lfEscapement;
-               v0->lpLogFont->lfOrientation = pwlf->lfOrientation;
-               v0->lpLogFont->lfWeight = pwlf->lfWeight;
-               v0->lpLogFont->lfItalic = pwlf->lfItalic;
-               v0->lpLogFont->lfUnderline = pwlf->lfUnderline;
-               v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;
-               v0->lpLogFont->lfCharSet = pwlf->lfCharSet;
-               v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;
-               v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;
-               v0->lpLogFont->lfQuality = pwlf->lfQuality;
-               v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;
-               WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);
-               TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);
-       }
-       v0->rgbColors = a0.rgbColors;
-       WtoM(v0->lpszStyle, LF_FACESIZE, a0.lpszStyle, -1);
-       TerminateStringM(v0->lpszStyle, LF_FACESIZE);
-       v0->nFontType = a0.nFontType;
-       if(pwlf)
-               free(pwlf);
-       FreeDuplicatedString(a0.lpTemplateName);
-       FreeDuplicatedString(a0.lpszStyle);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
-{
-       INT_PTR r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpTemplateName, -1);
-       r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-HWND CreateDialogParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
-{
-       HWND r = NULL;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(lpTemplateName, -1);
-       r = CreateDialogParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int mkdirM(const char * _Path)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Path, -1);
-       r = _wmkdir(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int _mkdirM(const char * _Path)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Path, -1);
-       r = _wmkdir(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int rmdirM(const char * _Path)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Path, -1);
-       r = _wrmdir(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-int _rmdirM(const char * _Path)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Path, -1);
-       r = _wrmdir(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-size_t _mbslenM(const unsigned char * _Str)
-{
-       size_t r = 0;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str, -1);
-       r = wcslen(pw0);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* wr;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str, -1);
-       // TODO: 非ASCII文字の対応
-       wr = wcschr(pw0, _Ch);
-       if(wr)
-       {
-               *wr = L'\0';
-               r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* wr;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str, -1);
-       // TODO: 非ASCII文字の対応
-       wr = wcsrchr(pw0, _Ch);
-       if(wr)
-       {
-               *wr = L'\0';
-               r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-       wchar_t* wr;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str, -1);
-       pw1 = DuplicateMtoW(_Substr, -1);
-       wr = wcsstr(pw0, pw1);
-       if(wr)
-       {
-               *wr = L'\0';
-               r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str1, -1);
-       pw1 = DuplicateMtoW(_Str2, -1);
-       r = wcscmp(pw0, pw1);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str1, -1);
-       pw1 = DuplicateMtoW(_Str2, -1);
-       r = _wcsicmp(pw0, pw1);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)
-{
-       int r = 0;
-       wchar_t* pw0 = NULL;
-       wchar_t* pw1 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str1, -1);
-       pw1 = DuplicateMtoW(_Str2, -1);
-       r = wcsncmp(pw0, pw1, _MaxCount);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       FreeDuplicatedString(pw1);
-       return r;
-}
-
-unsigned char * _mbslwrM(unsigned char * _String)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_String, -1);
-       _wcslwr(pw0);
-       r = _String;
-       WtoM(_String, strlen(_String) + 1, pw0, -1);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-unsigned char * _mbsuprM(unsigned char * _String)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_String, -1);
-       _wcsupr(pw0);
-       r = _String;
-       WtoM(_String, strlen(_String) + 1, pw0, -1);
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
-unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)
-{
-       unsigned char* r = NULL;
-       wchar_t* pw0 = NULL;
-       wchar_t* wr;
-START_ROUTINE
-       pw0 = DuplicateMtoW(_Str, -1);
-       wr = _wcsninc(pw0, _Count);
-       if(wr)
-       {
-               *wr = L'\0';
-               r = _Str + WtoM(NULL, 0, pw0, -1) - 1;
-       }
-END_ROUTINE
-       FreeDuplicatedString(pw0);
-       return r;
-}
-
+// mbswrapper.c\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// マルチバイト文字ワイド文字APIラッパー\r
+// マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
+// 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
+\r
+#define UNICODE\r
+#define _UNICODE\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+#include <direct.h>\r
+#include <windows.h>\r
+#include <commctrl.h>\r
+#include <shlobj.h>\r
+#include <htmlhelp.h>\r
+\r
+#define DO_NOT_REPLACE\r
+#include "mbswrapper.h"\r
+\r
+// マルチバイト文字列からワイド文字列へ変換\r
+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
+       return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
+       return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// Shift_JIS文字列からワイド文字列へ変換\r
+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
+       return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からShift_JIS文字列へ変換\r
+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
+       return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// マルチバイト文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringM(LPSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == '\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// ワイド文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringW(LPWSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == L'\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringA(LPSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == '\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数マルチバイト文字列の長さを取得\r
+size_t GetMultiStringLengthM(LPCSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数ワイド文字列の長さを取得\r
+size_t GetMultiStringLengthW(LPCWSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数Shift_JIS文字列の長さを取得\r
+size_t GetMultiStringLengthA(LPCSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列からワイド文字列へ変換\r
+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthM(pSrc);\r
+       i = 0;\r
+       while(*pSrc != '\0')\r
+       {\r
+               i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
+               pSrc += strlen(pSrc) + 1;\r
+       }\r
+       pDst[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からマルチバイト文字列へ変換\r
+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthW(pSrc);\r
+       i = 0;\r
+       while(*pSrc != L'\0')\r
+       {\r
+               i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+               pSrc += wcslen(pSrc) + 1;\r
+       }\r
+       pDst[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りShift_JIS文字列からワイド文字列へ変換\r
+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthA(pSrc);\r
+       i = 0;\r
+       while(*pSrc != '\0')\r
+       {\r
+               i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
+               pSrc += strlen(pSrc) + 1;\r
+       }\r
+       pDst[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からShift_JIS文字列へ変換\r
+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthW(pSrc);\r
+       i = 0;\r
+       while(*pSrc != L'\0')\r
+       {\r
+               i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+               pSrc += wcslen(pSrc) + 1;\r
+       }\r
+       pDst[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// マルチバイト文字列用のメモリを確保\r
+char* AllocateStringM(int size)\r
+{\r
+       char* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (char*)malloc(sizeof(char) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = '\0';\r
+       return p;\r
+}\r
+\r
+// ワイド文字列用のメモリを確保\r
+wchar_t* AllocateStringW(int size)\r
+{\r
+       wchar_t* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = L'\0';\r
+       return p;\r
+}\r
+\r
+// Shift_JIS文字列用のメモリを確保\r
+char* AllocateStringA(int size)\r
+{\r
+       char* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (char*)malloc(sizeof(char) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = '\0';\r
+       return p;\r
+}\r
+\r
+// メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = MtoW(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(size);\r
+       if(p)\r
+       {\r
+               i = MtoW(p, size, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
+{\r
+       int count;\r
+       wchar_t* p;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       count = GetMultiStringLengthM(lpString) + 1;\r
+       p = AllocateStringW(count);\r
+       if(p)\r
+               MtoW(p, count, lpString, count);\r
+       return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
+{\r
+       int count;\r
+       wchar_t* p;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       count = GetMultiStringLengthM(lpString) + 1;\r
+       p = AllocateStringW(size);\r
+       if(p)\r
+       {\r
+               MtoW(p, size, lpString, count);\r
+               p[size - 2] = L'\0';\r
+               p[size - 1] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoM(LPCWSTR lpString, int c)\r
+{\r
+       char* p;\r
+       int i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return (char*)lpString;\r
+       if(c < 0)\r
+               c = wcslen(lpString);\r
+       p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = WtoM(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = AtoW(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoA(LPCWSTR lpString, int c)\r
+{\r
+       char* p;\r
+       int i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return (char*)lpString;\r
+       if(c < 0)\r
+               c = wcslen(lpString);\r
+       p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = WtoA(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// マルチバイト文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+{\r
+       DWORD Code;\r
+       int i;\r
+       Code = 0;\r
+       if((*lpString & 0xfe) == 0xfc)\r
+       {\r
+               i = 5;\r
+               Code |= (DWORD)*lpString & 0x01;\r
+       }\r
+       else if((*lpString & 0xfc) == 0xf8)\r
+       {\r
+               i = 4;\r
+               Code |= (DWORD)*lpString & 0x03;\r
+       }\r
+       else if((*lpString & 0xf8) == 0xf0)\r
+       {\r
+               i = 3;\r
+               Code |= (DWORD)*lpString & 0x07;\r
+       }\r
+       else if((*lpString & 0xf0) == 0xe0)\r
+       {\r
+               i = 2;\r
+               Code |= (DWORD)*lpString & 0x0f;\r
+       }\r
+       else if((*lpString & 0xe0) == 0xc0)\r
+       {\r
+               i = 1;\r
+               Code |= (DWORD)*lpString & 0x1f;\r
+       }\r
+       else if((*lpString & 0x80) == 0x00)\r
+       {\r
+               i = 0;\r
+               Code |= (DWORD)*lpString & 0x7f;\r
+       }\r
+       else\r
+               i = -1;\r
+       if(*lpString != 0x00)\r
+       {\r
+               lpString++;\r
+               while((*lpString & 0xc0) == 0x80)\r
+               {\r
+                       i--;\r
+                       Code = Code << 6;\r
+                       Code |= (DWORD)*lpString & 0x3f;\r
+                       lpString++;\r
+               }\r
+       }\r
+       else\r
+               lpString++;\r
+       if(i != 0)\r
+               Code = 0x80000000;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       DWORD Code;\r
+       int i;\r
+       char c;\r
+       bResult = FALSE;\r
+       p = (char*)pSrc;\r
+       while(*pSrc != '\0')\r
+       {\r
+               Code = GetNextCharM(pSrc, &pSrc);\r
+               if(Code & 0x80000000)\r
+                       continue;\r
+               else if(Code & 0x7c000000)\r
+               {\r
+                       i = 5;\r
+                       c = (char)(0xfc | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x03e00000)\r
+               {\r
+                       i = 4;\r
+                       c = (char)(0xf8 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x001f0000)\r
+               {\r
+                       i = 3;\r
+                       c = (char)(0xf0 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x0000f800)\r
+               {\r
+                       i = 2;\r
+                       c = (char)(0xe0 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x00000780)\r
+               {\r
+                       i = 1;\r
+                       c = (char)(0xc0 | (Code >> (6 * i)));\r
+               }\r
+               else\r
+               {\r
+                       i = 0;\r
+                       c = (char)Code;\r
+               }\r
+               if(c != *p)\r
+                       bResult = TRUE;\r
+               p++;\r
+               *pDst = c;\r
+               pDst++;\r
+               while(i > 0)\r
+               {\r
+                       i--;\r
+                       c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));\r
+                       if(c != *p)\r
+                               bResult = TRUE;\r
+                       p++;\r
+                       *pDst = c;\r
+                       pDst++;\r
+               }\r
+       }\r
+       if(*p != '\0')\r
+               bResult = TRUE;\r
+       *pDst = '\0';\r
+       return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+       BOOL bResult;\r
+       int Length;\r
+       bResult = FALSE;\r
+       while(*pSrc != '\0')\r
+       {\r
+               Length = strlen(pSrc) + 1;\r
+               bResult = bResult | FixStringM(pDst, pSrc);\r
+               pSrc += Length;\r
+               pDst += strlen(pDst) + 1;\r
+       }\r
+       *pDst = '\0';\r
+       return bResult;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckStringM(LPCSTR lpString)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       bResult = FALSE;\r
+       p = AllocateStringM(strlen(lpString) + 1);\r
+       if(p)\r
+       {\r
+               bResult = FixStringM(p, lpString);\r
+               FreeDuplicatedString(p);\r
+       }\r
+       return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckMultiStringM(LPCSTR lpString)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       bResult = FALSE;\r
+       p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);\r
+       if(p)\r
+       {\r
+               bResult = FixMultiStringM(p, lpString);\r
+               FreeDuplicatedString(p);\r
+       }\r
+       return bResult;\r
+}\r
+\r
+// 文字列用に確保したメモリを開放\r
+// リソースIDならば何もしない\r
+void FreeDuplicatedString(void* p)\r
+{\r
+       if(p < (void*)0x00010000 || p == (void*)~0)\r
+               return;\r
+       free(p);\r
+}\r
+\r
+// 以下ラッパー\r
+// 戻り値バッファ r\r
+// ワイド文字バッファ pw%d\r
+// マルチバイト文字バッファ pm%d\r
+// 引数バッファ a%d\r
+\r
+#pragma warning(disable:4102)\r
+#define START_ROUTINE                                  do{\r
+#define END_ROUTINE                                            }while(0);end_of_routine:\r
+#define QUIT_ROUTINE                                   goto end_of_routine;\r
+\r
+int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)\r
+{\r
+       int r = 0;\r
+       char* pm0 = NULL;\r
+START_ROUTINE\r
+       pm0 = DuplicateWtoM(lpCmdLine, -1);\r
+       r = WinMainM(hInstance, hPrevInstance, pm0, nCmdShow);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pm0);\r
+       return r;\r
+}\r
+\r
+HMODULE LoadLibraryM(LPCSTR lpLibFileName)\r
+{\r
+       HMODULE r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpLibFileName, -1);\r
+       r = LoadLibraryW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
+{\r
+       HANDLE r = INVALID_HANDLE_VALUE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)\r
+{\r
+       int r = IDOK;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpText, -1);\r
+       pw1 = DuplicateMtoW(lpCaption, -1);\r
+       r = MessageBoxW(hWnd, pw0, pw1, uType);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+       HANDLE r = INVALID_HANDLE_VALUE;\r
+       wchar_t* pw0 = NULL;\r
+       WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = FindFirstFileW(pw0, &a0);\r
+       if(r != INVALID_HANDLE_VALUE)\r
+       {\r
+               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+               lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+               lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+               lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+       BOOL r = FALSE;\r
+       WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+       r = FindNextFileW(hFindFile, &a0);\r
+       if(r)\r
+       {\r
+               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+               lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+               lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+               lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+       }\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(nBufferLength * 4);\r
+       GetLogicalDriveStringsW(nBufferLength * 4, pw0);\r
+       WtoMMultiString(lpBuffer, nBufferLength, pw0);\r
+       r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)\r
+{\r
+       ATOM r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       WNDCLASSEXW a0;\r
+START_ROUTINE\r
+       a0.cbSize = sizeof(WNDCLASSEXW);\r
+       a0.style = v0->style;\r
+       a0.lpfnWndProc = v0->lpfnWndProc;\r
+       a0.cbClsExtra = v0->cbClsExtra;\r
+       a0.cbWndExtra = v0->cbWndExtra;\r
+       a0.hInstance = v0->hInstance;\r
+       a0.hIcon = v0->hIcon;\r
+       a0.hCursor = v0->hCursor;\r
+       a0.hbrBackground = v0->hbrBackground;\r
+       pw0 = DuplicateMtoW(v0->lpszMenuName, -1);\r
+       a0.lpszMenuName = pw0;\r
+       pw1 = DuplicateMtoW(v0->lpszClassName, -1);\r
+       a0.lpszClassName = pw1;\r
+       a0.hIconSm = v0->hIconSm;\r
+       r = RegisterClassExW(&a0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+HWND CreateWindowExM(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)\r
+{\r
+       HWND r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpClassName, -1);\r
+       pw1 = DuplicateMtoW(lpWindowName, -1);\r
+       r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+LONG GetWindowLongM(HWND hWnd, int nIndex)\r
+{\r
+       LONG r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = GetWindowLongW(hWnd, nIndex);\r
+       else\r
+               r = GetWindowLongA(hWnd, nIndex);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)\r
+{\r
+       LONG r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = SetWindowLongW(hWnd, nIndex, dwNewLong);\r
+       else\r
+               r = SetWindowLongA(hWnd, nIndex, dwNewLong);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LONG_PTR GetWindowLongPtrM(HWND hWnd, int nIndex)\r
+{\r
+       LONG_PTR r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = GetWindowLongPtrW(hWnd, nIndex);\r
+       else\r
+               r = GetWindowLongPtrA(hWnd, nIndex);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LONG_PTR SetWindowLongPtrM(HWND hWnd, int nIndex, LONG_PTR dwNewLong)\r
+{\r
+       LONG_PTR r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = SetWindowLongPtrW(hWnd, nIndex, dwNewLong);\r
+       else\r
+               r = SetWindowLongPtrA(hWnd, nIndex, dwNewLong);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+       LRESULT r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = DefWindowProcW(hWnd, Msg, wParam, lParam);\r
+       else\r
+               r = DefWindowProcA(hWnd, Msg, wParam, lParam);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+       LRESULT r = 0;\r
+START_ROUTINE\r
+       if(IsWindowUnicode(hWnd))\r
+               r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
+       else\r
+               r = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+       LRESULT r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       int Size;\r
+       LVITEMA* pmLVItem;\r
+       LVITEMW wLVItem;\r
+       LVFINDINFOA* pmLVFindInfo;\r
+       LVFINDINFOW wLVFindInfo;\r
+       LVCOLUMNA* pmLVColumn;\r
+       LVCOLUMNW wLVColumn;\r
+       TVITEMEXA* pmTVItem;\r
+       TVITEMEXW wTVItem;\r
+       TVINSERTSTRUCTA* pmTVInsert;\r
+       TVINSERTSTRUCTW wTVInsert;\r
+       wchar_t ClassName[MAX_PATH];\r
+START_ROUTINE\r
+       switch(Msg)\r
+       {\r
+       case WM_SETTEXT:\r
+               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+               r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);\r
+               break;\r
+       case WM_GETTEXT:\r
+               pw0 = AllocateStringW(wParam * 4);\r
+               SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);\r
+               WtoM((LPSTR)lParam, wParam, pw0, -1);\r
+               r = TerminateStringM((LPSTR)lParam, wParam);\r
+               break;\r
+       case WM_GETTEXTLENGTH:\r
+               Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, wParam, lParam) + 1;\r
+               pw0 = AllocateStringW(Size);\r
+               SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);\r
+               r = WtoM(NULL, 0, pw0, -1) - 1;\r
+               break;\r
+       default:\r
+               GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));\r
+               if(_wcsicmp(ClassName, WC_EDITW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case EM_REPLACESEL:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case CB_ADDSTRING:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       case CB_GETLBTEXT:\r
+                               Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
+                               pw0 = AllocateStringW(Size);\r
+                               SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);\r
+                               // バッファ長不明のためオーバーランの可能性あり\r
+                               WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
+                               r = TerminateStringM((LPSTR)lParam, Size * 4);\r
+                               break;\r
+                       case CB_GETLBTEXTLEN:\r
+                               Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
+                               pw0 = AllocateStringW(Size);\r
+                               SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
+                               r = WtoM(NULL, 0, pw0, -1) - 1;\r
+                               break;\r
+                       case CB_INSERTSTRING:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       case CB_FINDSTRINGEXACT:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case LB_ADDSTRING:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       case LB_INSERTSTRING:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       case LB_GETTEXT:\r
+                               Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
+                               pw0 = AllocateStringW(Size);\r
+                               SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);\r
+                               // バッファ長不明のためオーバーランの可能性あり\r
+                               WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
+                               r = TerminateStringM((LPSTR)lParam, Size * 4);\r
+                               break;\r
+                       case LB_GETTEXTLEN:\r
+                               Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
+                               pw0 = AllocateStringW(Size);\r
+                               SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
+                               r = WtoM(NULL, 0, pw0, -1) - 1;\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case LVM_GETITEMA:\r
+                               pmLVItem = (LVITEMA*)lParam;\r
+                               wLVItem.mask = pmLVItem->mask;\r
+                               wLVItem.iItem = pmLVItem->iItem;\r
+                               wLVItem.iSubItem = pmLVItem->iSubItem;\r
+                               wLVItem.state = pmLVItem->state;\r
+                               wLVItem.stateMask = pmLVItem->stateMask;\r
+                               if(pmLVItem->mask & LVIF_TEXT)\r
+                               {\r
+                                       Size = pmLVItem->cchTextMax * 4;\r
+                                       pw0 = AllocateStringW(Size);\r
+                                       wLVItem.pszText = pw0;\r
+                                       wLVItem.cchTextMax = Size;\r
+                               }\r
+                               wLVItem.iImage = pmLVItem->iImage;\r
+                               wLVItem.lParam = pmLVItem->lParam;\r
+                               wLVItem.iIndent = pmLVItem->iIndent;\r
+                               r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);\r
+                               pmLVItem->mask = wLVItem.mask;\r
+                               pmLVItem->iItem = wLVItem.iItem;\r
+                               pmLVItem->iSubItem = wLVItem.iSubItem;\r
+                               pmLVItem->state = wLVItem.state;\r
+                               pmLVItem->stateMask = wLVItem.stateMask;\r
+                               if(pmLVItem->mask & LVIF_TEXT)\r
+                               {\r
+                                       WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
+                                       TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
+                               }\r
+                               pmLVItem->iImage = wLVItem.iImage;\r
+                               pmLVItem->lParam = wLVItem.lParam;\r
+                               pmLVItem->iIndent = wLVItem.iIndent;\r
+                               break;\r
+                       case LVM_SETITEMA:\r
+                               pmLVItem = (LVITEMA*)lParam;\r
+                               wLVItem.mask = pmLVItem->mask;\r
+                               wLVItem.iItem = pmLVItem->iItem;\r
+                               wLVItem.iSubItem = pmLVItem->iSubItem;\r
+                               wLVItem.state = pmLVItem->state;\r
+                               wLVItem.stateMask = pmLVItem->stateMask;\r
+                               if(pmLVItem->mask & LVIF_TEXT)\r
+                               {\r
+                                       pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
+                                       wLVItem.pszText = pw0;\r
+                                       // TODO: cchTextMaxの確認\r
+                                       wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
+                               }\r
+                               wLVItem.iImage = pmLVItem->iImage;\r
+                               wLVItem.lParam = pmLVItem->lParam;\r
+                               wLVItem.iIndent = pmLVItem->iIndent;\r
+                               r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);\r
+                               break;\r
+                       case LVM_INSERTITEMA:\r
+                               pmLVItem = (LVITEMA*)lParam;\r
+                               wLVItem.mask = pmLVItem->mask;\r
+                               wLVItem.iItem = pmLVItem->iItem;\r
+                               wLVItem.iSubItem = pmLVItem->iSubItem;\r
+                               wLVItem.state = pmLVItem->state;\r
+                               wLVItem.stateMask = pmLVItem->stateMask;\r
+                               if(pmLVItem->mask & LVIF_TEXT)\r
+                               {\r
+                                       pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
+                                       wLVItem.pszText = pw0;\r
+                                       // TODO: cchTextMaxの確認\r
+                                       wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
+                               }\r
+                               wLVItem.iImage = pmLVItem->iImage;\r
+                               wLVItem.lParam = pmLVItem->lParam;\r
+                               wLVItem.iIndent = pmLVItem->iIndent;\r
+                               r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);\r
+                               break;\r
+                       case LVM_FINDITEMA:\r
+                               pmLVFindInfo = (LVFINDINFOA*)lParam;\r
+                               wLVFindInfo.flags = pmLVFindInfo->flags;\r
+                               if(pmLVFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))\r
+                               {\r
+                                       pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);\r
+                                       wLVFindInfo.psz = pw0;\r
+                               }\r
+                               wLVFindInfo.lParam = pmLVFindInfo->lParam;\r
+                               wLVFindInfo.pt = pmLVFindInfo->pt;\r
+                               wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;\r
+                               r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);\r
+                               break;\r
+                       case LVM_GETCOLUMNA:\r
+                               pmLVColumn = (LVCOLUMNA*)lParam;\r
+                               wLVColumn.mask = pmLVColumn->mask;\r
+                               wLVColumn.fmt = pmLVColumn->fmt;\r
+                               wLVColumn.cx = pmLVColumn->cx;\r
+                               Size = pmLVColumn->cchTextMax * 4;\r
+                               if(pmLVColumn->mask & LVCF_TEXT)\r
+                               {\r
+                                       pw0 = AllocateStringW(Size);\r
+                                       wLVColumn.pszText = pw0;\r
+                                       wLVColumn.cchTextMax = Size;\r
+                               }\r
+                               wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
+                               wLVColumn.iImage = pmLVColumn->iImage;\r
+                               wLVColumn.iOrder = pmLVColumn->iOrder;\r
+                               r = SendMessageW(hWnd, LVM_GETCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
+                               pmLVColumn->mask = wLVColumn.mask;\r
+                               pmLVColumn->fmt = wLVColumn.fmt;\r
+                               pmLVColumn->cx = wLVColumn.cx;\r
+                               if(pmLVColumn->mask & LVCF_TEXT)\r
+                               {\r
+                                       WtoM(pmLVColumn->pszText, pmLVColumn->cchTextMax, wLVColumn.pszText, -1);\r
+                                       TerminateStringM(pmLVColumn->pszText, pmLVColumn->cchTextMax);\r
+                               }\r
+                               pmLVColumn->iSubItem = wLVColumn.iSubItem;\r
+                               pmLVColumn->iImage = wLVColumn.iImage;\r
+                               pmLVColumn->iOrder = wLVColumn.iOrder;\r
+                               break;\r
+                       case LVM_INSERTCOLUMNA:\r
+                               pmLVColumn = (LVCOLUMNA*)lParam;\r
+                               wLVColumn.mask = pmLVColumn->mask;\r
+                               wLVColumn.fmt = pmLVColumn->fmt;\r
+                               wLVColumn.cx = pmLVColumn->cx;\r
+                               if(pmLVColumn->mask & LVCF_TEXT)\r
+                               {\r
+                                       pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);\r
+                                       wLVColumn.pszText = pw0;\r
+                                       // TODO: cchTextMaxの確認\r
+                                       wLVColumn.cchTextMax = pmLVColumn->cchTextMax;\r
+                               }\r
+                               wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
+                               wLVColumn.iImage = pmLVColumn->iImage;\r
+                               wLVColumn.iOrder = pmLVColumn->iOrder;\r
+                               r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
+                               break;\r
+                       case LVM_GETITEMTEXTA:\r
+                               pmLVItem = (LVITEMA*)lParam;\r
+                               wLVItem.mask = pmLVItem->mask;\r
+                               wLVItem.iItem = pmLVItem->iItem;\r
+                               wLVItem.iSubItem = pmLVItem->iSubItem;\r
+                               wLVItem.state = pmLVItem->state;\r
+                               wLVItem.stateMask = pmLVItem->stateMask;\r
+                               Size = pmLVItem->cchTextMax * 4;\r
+                               pw0 = AllocateStringW(Size);\r
+                               wLVItem.pszText = pw0;\r
+                               wLVItem.cchTextMax = Size;\r
+                               wLVItem.iImage = pmLVItem->iImage;\r
+                               wLVItem.lParam = pmLVItem->lParam;\r
+                               wLVItem.iIndent = pmLVItem->iIndent;\r
+                               r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);\r
+                               pmLVItem->mask = wLVItem.mask;\r
+                               pmLVItem->iItem = wLVItem.iItem;\r
+                               pmLVItem->iSubItem = wLVItem.iSubItem;\r
+                               pmLVItem->state = wLVItem.state;\r
+                               pmLVItem->stateMask = wLVItem.stateMask;\r
+                               WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
+                               TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
+                               pmLVItem->iImage = wLVItem.iImage;\r
+                               pmLVItem->lParam = wLVItem.lParam;\r
+                               pmLVItem->iIndent = wLVItem.iIndent;\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case SB_SETTEXTA:\r
+                               pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
+                               r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else if(_wcsicmp(ClassName, WC_TREEVIEWW) == 0)\r
+               {\r
+                       switch(Msg)\r
+                       {\r
+                       case TVM_GETITEMA:\r
+                               pmTVItem = (TVITEMEXA*)lParam;\r
+                               wTVItem.mask = pmTVItem->mask;\r
+                               wTVItem.hItem = pmTVItem->hItem;\r
+                               wTVItem.state = pmTVItem->state;\r
+                               wTVItem.stateMask = pmTVItem->stateMask;\r
+                               if(pmTVItem->mask & TVIF_TEXT)\r
+                               {\r
+                                       Size = pmTVItem->cchTextMax * 4;\r
+                                       pw0 = AllocateStringW(Size);\r
+                                       wTVItem.pszText = pw0;\r
+                                       wTVItem.cchTextMax = Size;\r
+                               }\r
+                               wTVItem.iImage = pmTVItem->iImage;\r
+                               wTVItem.iSelectedImage = pmTVItem->iSelectedImage;\r
+                               wTVItem.cChildren = pmTVItem->cChildren;\r
+                               wTVItem.lParam = pmTVItem->lParam;\r
+                               wTVItem.iIntegral = pmTVItem->iIntegral;\r
+//                             wTVItem.uStateEx = pmTVItem->uStateEx;\r
+//                             wTVItem.hwnd = pmTVItem->hwnd;\r
+//                             wTVItem.iExpandedImage = pmTVItem->iExpandedImage;\r
+//                             wTVItem.iReserved = pmTVItem->iReserved;\r
+                               r = SendMessageW(hWnd, TVM_GETITEMW, wParam, (LPARAM)&wTVItem);\r
+                               pmTVItem->mask = wTVItem.mask;\r
+                               pmTVItem->hItem = wTVItem.hItem;\r
+                               pmTVItem->state = wTVItem.state;\r
+                               pmTVItem->stateMask = wTVItem.stateMask;\r
+                               if(pmTVItem->mask & TVIF_TEXT)\r
+                               {\r
+                                       WtoM(pmTVItem->pszText, pmTVItem->cchTextMax, wTVItem.pszText, -1);\r
+                                       TerminateStringM(pmTVItem->pszText, pmTVItem->cchTextMax);\r
+                               }\r
+                               pmTVItem->iImage = wTVItem.iImage;\r
+                               pmTVItem->iSelectedImage = wTVItem.iSelectedImage;\r
+                               pmTVItem->cChildren = wTVItem.cChildren;\r
+                               pmTVItem->lParam = wTVItem.lParam;\r
+                               pmTVItem->iIntegral = wTVItem.iIntegral;\r
+//                             pmTVItem->uStateEx = wTVItem.uStateEx;\r
+//                             pmTVItem->hwnd = wTVItem.hwnd;\r
+//                             pmTVItem->iExpandedImage = wTVItem.iExpandedImage;\r
+//                             pmTVItem->iReserved = wTVItem.iReserved;\r
+                               break;\r
+                       case TVM_INSERTITEMA:\r
+                               pmTVInsert = (TVINSERTSTRUCTA*)lParam;\r
+                               wTVInsert.hParent = pmTVInsert->hParent;\r
+                               wTVInsert.hInsertAfter = pmTVInsert->hInsertAfter;\r
+                               wTVInsert.itemex.mask = pmTVInsert->itemex.mask;\r
+                               wTVInsert.itemex.hItem = pmTVInsert->itemex.hItem;\r
+                               wTVInsert.itemex.state = pmTVInsert->itemex.state;\r
+                               wTVInsert.itemex.stateMask = pmTVInsert->itemex.stateMask;\r
+                               if(pmTVInsert->itemex.mask & TVIF_TEXT)\r
+                               {\r
+                                       pw0 = DuplicateMtoW(pmTVInsert->itemex.pszText, -1);\r
+                                       wTVInsert.itemex.pszText = pw0;\r
+                                       // TODO: cchTextMaxの確認\r
+                                       wTVInsert.itemex.cchTextMax = pmTVInsert->itemex.cchTextMax;\r
+                               }\r
+                               wTVInsert.itemex.iImage = pmTVInsert->itemex.iImage;\r
+                               wTVInsert.itemex.iSelectedImage = pmTVInsert->itemex.iSelectedImage;\r
+                               wTVInsert.itemex.cChildren = pmTVInsert->itemex.cChildren;\r
+                               wTVInsert.itemex.lParam = pmTVInsert->itemex.lParam;\r
+                               wTVInsert.itemex.iIntegral = pmTVInsert->itemex.iIntegral;\r
+//                             wTVInsert.itemex.uStateEx = pmTVInsert->itemex.uStateEx;\r
+//                             wTVInsert.itemex.hwnd = pmTVInsert->itemex.hwnd;\r
+//                             wTVInsert.itemex.iExpandedImage = pmTVInsert->itemex.iExpandedImage;\r
+//                             wTVInsert.itemex.iReserved = pmTVInsert->itemex.iReserved;\r
+                               r = SendMessageW(hWnd, TVM_INSERTITEMW, wParam, (LPARAM)&wTVInsert);\r
+                               break;\r
+                       default:\r
+                               r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       r = SendMessageW(hWnd, Msg, wParam, lParam);\r
+               break;\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+LRESULT DefDlgProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+       LRESULT r = 0;\r
+START_ROUTINE\r
+       // WNDPROCがShift_JIS用であるため\r
+       if(IsWindowUnicode(hWnd))\r
+               r = DefDlgProcW(hWnd, Msg, wParam, lParam);\r
+       else\r
+               r = DefDlgProcA(hWnd, Msg, wParam, lParam);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+       LRESULT r = 0;\r
+START_ROUTINE\r
+       r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpString, -1);\r
+       r = SetWindowTextW(hWnd, pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)\r
+{\r
+       UINT r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       if(iFile == (UINT)-1)\r
+               r = DragQueryFileW(hDrop, iFile, (LPWSTR)lpszFile, cch);\r
+       else\r
+       {\r
+               pw0 = AllocateStringW(cch * 4);\r
+               DragQueryFileW(hDrop, iFile, pw0, cch * 4);\r
+               WtoM(lpszFile, cch, pw0, -1);\r
+               r = TerminateStringM(lpszFile, cch);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+LPSTR GetCommandLineM()\r
+{\r
+       LPSTR r = 0;\r
+       static char* pm0 = NULL;\r
+START_ROUTINE\r
+       if(!pm0)\r
+               pm0 = DuplicateWtoM(GetCommandLineW(), -1);\r
+       r = pm0;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       // TODO: バッファが不十分な場合に必要なサイズを返す\r
+       pw0 = AllocateStringW(nBufferLength * 4);\r
+       GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
+       WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+       r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpPathName, -1);\r
+       r = SetCurrentDirectoryW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(nBufferLength * 4);\r
+       GetTempPathW(nBufferLength * 4, pw0);\r
+       WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+       r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetFileAttributesM(LPCSTR lpFileName)\r
+{\r
+       DWORD r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = GetFileAttributesW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(nSize * 4);\r
+       GetModuleFileNameW(hModule, pw0, nSize * 4);\r
+       WtoM(lpFilename, nSize, pw0, -1);\r
+       r = TerminateStringM(lpFilename, nSize);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)\r
+{\r
+       LSTATUS r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpSubKey, -1);\r
+       r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)\r
+{\r
+       LSTATUS r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpSubKey, -1);\r
+       pw1 = DuplicateMtoW(lpClass, -1);\r
+       r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)\r
+{\r
+       LSTATUS r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpValueName, -1);\r
+       r = RegDeleteValueW(hKey, pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)\r
+{\r
+       LSTATUS r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       DWORD dwType;\r
+       DWORD wcbData;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpValueName, -1);\r
+       if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)\r
+       {\r
+               switch(dwType)\r
+               {\r
+               case REG_SZ:\r
+               case REG_EXPAND_SZ:\r
+               case REG_MULTI_SZ:\r
+                       if(lpcbData)\r
+                       {\r
+                               pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);\r
+                               wcbData = *lpcbData / sizeof(char) * 4;\r
+                               r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);\r
+                               if(lpData)\r
+                                       *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));\r
+                               else\r
+                                       *lpcbData = sizeof(char) * WtoM(NULL, 0, pw1, wcbData / sizeof(wchar_t));\r
+                       }\r
+                       break;\r
+               default:\r
+                       r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
+                       break;\r
+               }\r
+       }\r
+       else\r
+               r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)\r
+{\r
+       LSTATUS r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       DWORD wcbData;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpValueName, -1);\r
+       switch(dwType)\r
+       {\r
+       case REG_SZ:\r
+       case REG_EXPAND_SZ:\r
+       case REG_MULTI_SZ:\r
+               wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));\r
+               pw1 = AllocateStringW(wcbData);\r
+               MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));\r
+               wcbData = sizeof(wchar_t) * wcbData;\r
+               lpData = (BYTE*)pw1;\r
+               cbData = wcbData;\r
+               break;\r
+       }\r
+       r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpString, c);\r
+       r = TextOutW(hdc, x, y, pw0, wcslen(pw0));\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpString, c);\r
+       r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)\r
+{\r
+       INT_PTR r = 0;\r
+       PROPSHEETHEADERW a0;\r
+       PROPSHEETPAGEW* pwPage;\r
+       UINT i;\r
+START_ROUTINE\r
+       a0.dwSize = sizeof(PROPSHEETHEADERW);\r
+       a0.dwFlags = v0->dwFlags;\r
+       a0.hwndParent = v0->hwndParent;\r
+       a0.hInstance = v0->hInstance;\r
+       if(v0->dwFlags & PSH_USEICONID)\r
+               a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);\r
+       else\r
+               a0.hIcon = v0->hIcon;\r
+       a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);\r
+       a0.nPages = v0->nPages;\r
+       if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
+               a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);\r
+       else\r
+               a0.nStartPage = v0->nStartPage;\r
+       if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
+       {\r
+               if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))\r
+               {\r
+                       for(i = 0; i < v0->nPages; i++)\r
+                       {\r
+                               pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);\r
+                               pwPage[i].dwFlags = v0->ppsp[i].dwFlags;\r
+                               pwPage[i].hInstance = v0->ppsp[i].hInstance;\r
+                               if(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT)\r
+                                       pwPage[i].pResource = v0->ppsp[i].pResource;\r
+                               else\r
+                                       pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
+                                       pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);\r
+                               else\r
+                                       pwPage[i].hIcon = v0->ppsp[i].hIcon;\r
+                               if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
+                                       pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);\r
+                               pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;\r
+                               pwPage[i].lParam = v0->ppsp[i].lParam;\r
+                               // TODO: pfnCallback\r
+                               pwPage[i].pfnCallback = (LPFNPSPCALLBACKW)v0->ppsp[i].pfnCallback;\r
+                               pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
+                                       pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
+                                       pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);\r
+                       }\r
+               }\r
+               else\r
+                       pwPage = NULL;\r
+               a0.ppsp = pwPage;\r
+       }\r
+       else\r
+               a0.phpage = v0->phpage;\r
+       a0.pfnCallback = v0->pfnCallback;\r
+       if(v0->dwFlags & PSH_USEHBMWATERMARK)\r
+               a0.hbmWatermark = v0->hbmWatermark;\r
+       else\r
+               a0.pszbmWatermark = DuplicateMtoW(v0->pszbmWatermark, -1);\r
+       r = PropertySheetW(&a0);\r
+       if(a0.dwFlags & PSH_USEICONID)\r
+               FreeDuplicatedString((void*)a0.pszIcon);\r
+       FreeDuplicatedString((void*)a0.pszCaption);\r
+       if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
+               FreeDuplicatedString((void*)a0.pStartPage);\r
+       if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
+       {\r
+               if(pwPage)\r
+               {\r
+                       for(i = 0; i < v0->nPages; i++)\r
+                       {\r
+                               if(!(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT))\r
+                                       FreeDuplicatedString((void*)pwPage[i].pszTemplate);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
+                                       FreeDuplicatedString((void*)pwPage[i].pszIcon);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
+                                       FreeDuplicatedString((void*)pwPage[i].pszTitle);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
+                                       FreeDuplicatedString((void*)pwPage[i].pszHeaderTitle);\r
+                               if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
+                                       FreeDuplicatedString((void*)pwPage[i].pszHeaderSubTitle);\r
+                       }\r
+                       free(pwPage);\r
+               }\r
+       }\r
+       if(!(v0->dwFlags & PSH_USEHBMWATERMARK))\r
+               FreeDuplicatedString((void*)a0.pszbmWatermark);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+       wchar_t* pw4 = NULL;\r
+       wchar_t* pw5 = NULL;\r
+       wchar_t* pw6 = NULL;\r
+       wchar_t* pw7 = NULL;\r
+       wchar_t* pw8 = NULL;\r
+       wchar_t* pw9 = NULL;\r
+       OPENFILENAMEW wofn;\r
+START_ROUTINE\r
+       wofn.lStructSize = sizeof(OPENFILENAMEW);\r
+       wofn.hwndOwner = v0->hwndOwner;\r
+       wofn.hInstance = v0->hInstance;\r
+       pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
+       wofn.lpstrFilter = pw0;\r
+       pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
+       wofn.lpstrCustomFilter = pw1;\r
+       wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
+       wofn.nFilterIndex = v0->nFilterIndex;\r
+       pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
+       wofn.lpstrFile = pw2;\r
+       wofn.nMaxFile = v0->nMaxFile * 4;\r
+       pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
+       wofn.lpstrFileTitle = pw3;\r
+       wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
+       pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
+       wofn.lpstrInitialDir = pw4;\r
+       pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
+       wofn.lpstrTitle = pw5;\r
+       wofn.Flags = v0->Flags;\r
+       wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
+       wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
+       pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
+       wofn.lpstrDefExt = pw6;\r
+       wofn.lCustData = v0->lCustData;\r
+       wofn.lpfnHook = v0->lpfnHook;\r
+       wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
+       wofn.pvReserved = v0->pvReserved;\r
+       wofn.FlagsEx = v0->FlagsEx;\r
+       r = GetOpenFileNameW(&wofn);\r
+       WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
+       TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
+       v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
+       v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       FreeDuplicatedString(pw4);\r
+       FreeDuplicatedString(pw5);\r
+       FreeDuplicatedString(pw6);\r
+       return r;\r
+}\r
+\r
+BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+       wchar_t* pw4 = NULL;\r
+       wchar_t* pw5 = NULL;\r
+       wchar_t* pw6 = NULL;\r
+       wchar_t* pw7 = NULL;\r
+       wchar_t* pw8 = NULL;\r
+       wchar_t* pw9 = NULL;\r
+       OPENFILENAMEW wofn;\r
+START_ROUTINE\r
+       wofn.lStructSize = sizeof(OPENFILENAMEW);\r
+       wofn.hwndOwner = v0->hwndOwner;\r
+       wofn.hInstance = v0->hInstance;\r
+       pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
+       wofn.lpstrFilter = pw0;\r
+       pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
+       wofn.lpstrCustomFilter = pw1;\r
+       wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
+       wofn.nFilterIndex = v0->nFilterIndex;\r
+       pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
+       wofn.lpstrFile = pw2;\r
+       wofn.nMaxFile = v0->nMaxFile * 4;\r
+       pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
+       wofn.lpstrFileTitle = pw3;\r
+       wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
+       pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
+       wofn.lpstrInitialDir = pw4;\r
+       pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
+       wofn.lpstrTitle = pw5;\r
+       wofn.Flags = v0->Flags;\r
+       wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
+       wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
+       pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
+       wofn.lpstrDefExt = pw6;\r
+       wofn.lCustData = v0->lCustData;\r
+       wofn.lpfnHook = v0->lpfnHook;\r
+       wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
+       wofn.pvReserved = v0->pvReserved;\r
+       wofn.FlagsEx = v0->FlagsEx;\r
+       r = GetSaveFileNameW(&wofn);\r
+       WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
+       TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
+       v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
+       v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       FreeDuplicatedString(pw4);\r
+       FreeDuplicatedString(pw5);\r
+       FreeDuplicatedString(pw6);\r
+       return r;\r
+}\r
+\r
+HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)\r
+{\r
+       HWND r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(pszFile, -1);\r
+       r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL CreateProcessM(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+       wchar_t* pw4 = NULL;\r
+       wchar_t* pw5 = NULL;\r
+       STARTUPINFOW wStartupInfo;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpApplicationName, -1);\r
+       pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);\r
+       pw2 = DuplicateMtoW(lpCurrentDirectory, -1);\r
+       wStartupInfo.cb = sizeof(LPSTARTUPINFOW);\r
+       pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);\r
+       wStartupInfo.lpReserved = pw3;\r
+       pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);\r
+       wStartupInfo.lpDesktop = pw4;\r
+       pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);\r
+       wStartupInfo.lpTitle = pw5;\r
+       wStartupInfo.dwX = lpStartupInfo->dwX;\r
+       wStartupInfo.dwY = lpStartupInfo->dwY;\r
+       wStartupInfo.dwXSize = lpStartupInfo->dwXSize;\r
+       wStartupInfo.dwYSize = lpStartupInfo->dwYSize;\r
+       wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;\r
+       wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;\r
+       wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;\r
+       wStartupInfo.dwFlags = lpStartupInfo->dwFlags;\r
+       wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;\r
+       wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;\r
+       wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;\r
+       wStartupInfo.hStdInput = lpStartupInfo->hStdInput;\r
+       wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;\r
+       wStartupInfo.hStdError = lpStartupInfo->hStdError;\r
+       r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);\r
+       WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       FreeDuplicatedString(pw4);\r
+       FreeDuplicatedString(pw5);\r
+       return r;\r
+}\r
+\r
+HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)\r
+{\r
+       HINSTANCE r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFile, -1);\r
+       pw1 = DuplicateMtoW(lpDirectory, -1);\r
+       pw2 = AllocateStringW(MAX_PATH * 4);\r
+       r = FindExecutableW(pw0, pw1, pw2);\r
+       // バッファ長不明のためオーバーランの可能性あり\r
+       WtoM(lpResult, MAX_PATH, pw2, -1);\r
+       TerminateStringM(lpResult, MAX_PATH);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       return r;\r
+}\r
+\r
+HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)\r
+{\r
+       HINSTANCE r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpOperation, -1);\r
+       pw1 = DuplicateMtoW(lpFile, -1);\r
+       pw2 = DuplicateMtoW(lpParameters, -1);\r
+       pw3 = DuplicateMtoW(lpDirectory, -1);\r
+       r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       return r;\r
+}\r
+\r
+BOOL ShellExecuteExM(LPSHELLEXECUTEINFOA lpExecInfo)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       wchar_t* pw3 = NULL;\r
+       wchar_t* pw4 = NULL;\r
+       SHELLEXECUTEINFOW wExecInfo;\r
+START_ROUTINE\r
+       wExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);\r
+       wExecInfo.fMask = lpExecInfo->fMask;\r
+       wExecInfo.hwnd = lpExecInfo->hwnd;\r
+       pw0 = DuplicateMtoW(lpExecInfo->lpVerb, -1);\r
+       wExecInfo.lpVerb = pw0;\r
+       pw1 = DuplicateMtoW(lpExecInfo->lpFile, -1);\r
+       wExecInfo.lpFile = pw1;\r
+       pw2 = DuplicateMtoW(lpExecInfo->lpParameters, -1);\r
+       wExecInfo.lpParameters = pw2;\r
+       pw3 = DuplicateMtoW(lpExecInfo->lpDirectory, -1);\r
+       wExecInfo.lpDirectory = pw3;\r
+       wExecInfo.nShow = lpExecInfo->nShow;\r
+       wExecInfo.hInstApp = lpExecInfo->hInstApp;\r
+       wExecInfo.lpIDList = lpExecInfo->lpIDList;\r
+       if(lpExecInfo->fMask & SEE_MASK_CLASSNAME)\r
+       {\r
+               pw4 = DuplicateMtoW(lpExecInfo->lpClass, -1);\r
+               wExecInfo.lpClass = pw4;\r
+       }\r
+       wExecInfo.hkeyClass = lpExecInfo->hkeyClass;\r
+       wExecInfo.dwHotKey = lpExecInfo->dwHotKey;\r
+       wExecInfo.hIcon = lpExecInfo->hIcon;\r
+       wExecInfo.hProcess = lpExecInfo->hProcess;\r
+       r = ShellExecuteExW(&wExecInfo);\r
+       lpExecInfo->hInstApp = wExecInfo.hInstApp;\r
+       lpExecInfo->hProcess = wExecInfo.hProcess;\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       FreeDuplicatedString(pw3);\r
+       FreeDuplicatedString(pw4);\r
+       return r;\r
+}\r
+\r
+PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)\r
+{\r
+       PIDLIST_ABSOLUTE r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       BROWSEINFOW wbi;\r
+START_ROUTINE\r
+       wbi.hwndOwner = lpbi->hwndOwner;\r
+       wbi.pidlRoot = lpbi->pidlRoot;\r
+       pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);\r
+       wbi.pszDisplayName = pw0;\r
+       pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);\r
+       wbi.lpszTitle = pw1;\r
+       wbi.ulFlags = lpbi->ulFlags;\r
+       // TODO: lpfn\r
+       wbi.lpfn = lpbi->lpfn;\r
+       wbi.lParam = lpbi->lParam;\r
+       wbi.iImage = lpbi->iImage;\r
+       r = SHBrowseForFolderW(&wbi);\r
+       // バッファ長不明のためオーバーランの可能性あり\r
+       WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);\r
+       lpbi->iImage = wbi.iImage;\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(MAX_PATH * 4);\r
+       r = SHGetPathFromIDListW(pidl, pw0);\r
+       // バッファ長不明のためオーバーランの可能性あり\r
+       WtoM(pszPath, MAX_PATH, pw0, -1);\r
+       TerminateStringM(pszPath, MAX_PATH);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)\r
+{\r
+       int r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       wchar_t* pw2 = NULL;\r
+       SHFILEOPSTRUCTW wFileOp;\r
+START_ROUTINE\r
+       wFileOp.hwnd = lpFileOp->hwnd;\r
+       wFileOp.wFunc = lpFileOp->wFunc;\r
+       pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);\r
+       wFileOp.pFrom = pw0;\r
+       pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);\r
+       wFileOp.pTo = pw1;\r
+       wFileOp.fFlags = lpFileOp->fFlags;\r
+       wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;\r
+       wFileOp.hNameMappings = lpFileOp->hNameMappings;\r
+       if(lpFileOp->fFlags & FOF_SIMPLEPROGRESS)\r
+               pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);\r
+       r = SHFileOperationW(&wFileOp);\r
+       lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       FreeDuplicatedString(pw2);\r
+       return r;\r
+}\r
+\r
+DWORD_PTR SHGetFileInfoM(LPCSTR pszPath, DWORD dwFileAttributes, SHFILEINFOA *psfi, UINT cbFileInfo, UINT uFlags)\r
+{\r
+       DWORD_PTR r = 0;\r
+       wchar_t* pw0 = NULL;\r
+       SHFILEINFOW wsfi;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoWMultiString(pszPath);\r
+       if((r = SHGetFileInfoW(pw0, dwFileAttributes, &wsfi, cbFileInfo, uFlags)) != 0)\r
+       {\r
+               psfi->hIcon = wsfi.hIcon;\r
+               psfi->iIcon = wsfi.iIcon;\r
+               psfi->dwAttributes = wsfi.dwAttributes;\r
+               WtoM(psfi->szDisplayName, MAX_PATH, wsfi.szDisplayName, -1);\r
+               WtoM(psfi->szTypeName, 80, wsfi.szTypeName, -1);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)\r
+{\r
+       int r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       if(uFlags & (MF_BITMAP | MF_OWNERDRAW))\r
+               r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);\r
+       else\r
+       {\r
+               pw0 = DuplicateMtoW(lpNewItem, -1);\r
+               r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       MENUITEMINFOW wmii;\r
+START_ROUTINE\r
+       wmii.cbSize = sizeof(MENUITEMINFOW);\r
+       wmii.fMask = lpmii->fMask;\r
+       wmii.fType = lpmii->fType;\r
+       wmii.fState = lpmii->fState;\r
+       wmii.wID = lpmii->wID;\r
+       wmii.hSubMenu = lpmii->hSubMenu;\r
+       wmii.hbmpChecked = lpmii->hbmpChecked;\r
+       wmii.hbmpUnchecked = lpmii->hbmpUnchecked;\r
+       wmii.dwItemData = lpmii->dwItemData;\r
+       if(lpmii->fMask & MIIM_TYPE)\r
+       {\r
+               pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);\r
+               wmii.dwTypeData = pw0;\r
+               wmii.cch = lpmii->cch * 4;\r
+       }\r
+       wmii.hbmpItem = lpmii->hbmpItem;\r
+       r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);\r
+       lpmii->fType = wmii.fType;\r
+       lpmii->fState = wmii.fState;\r
+       lpmii->wID = wmii.wID;\r
+       lpmii->hSubMenu = wmii.hSubMenu;\r
+       lpmii->hbmpChecked = wmii.hbmpChecked;\r
+       lpmii->hbmpUnchecked = wmii.hbmpUnchecked;\r
+       lpmii->dwItemData = wmii.dwItemData;\r
+       WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);\r
+       TerminateStringM(lpmii->dwTypeData, lpmii->cch);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)\r
+{\r
+       HFONT r = NULL;\r
+       LOGFONTW wlf;\r
+START_ROUTINE\r
+       wlf.lfHeight = lplf->lfHeight;\r
+       wlf.lfWidth = lplf->lfWidth;\r
+       wlf.lfEscapement = lplf->lfEscapement;\r
+       wlf.lfOrientation = lplf->lfOrientation;\r
+       wlf.lfWeight = lplf->lfWeight;\r
+       wlf.lfItalic = lplf->lfItalic;\r
+       wlf.lfUnderline = lplf->lfUnderline;\r
+       wlf.lfStrikeOut = lplf->lfStrikeOut;\r
+       wlf.lfCharSet = lplf->lfCharSet;\r
+       wlf.lfOutPrecision = lplf->lfOutPrecision;\r
+       wlf.lfClipPrecision = lplf->lfClipPrecision;\r
+       wlf.lfQuality = lplf->lfQuality;\r
+       wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;\r
+       MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);\r
+       TerminateStringW(wlf.lfFaceName, LF_FACESIZE);\r
+       r = CreateFontIndirect(&wlf);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+BOOL ChooseFontM(LPCHOOSEFONTA v0)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+       CHOOSEFONTW a0;\r
+       LOGFONTW* pwlf;\r
+START_ROUTINE\r
+       a0.lStructSize = sizeof(CHOOSEFONTW);\r
+       a0.hwndOwner = v0->hwndOwner;\r
+       a0.hDC = v0->hDC;\r
+       if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))\r
+       {\r
+               pwlf->lfHeight = v0->lpLogFont->lfHeight;\r
+               pwlf->lfWidth = v0->lpLogFont->lfWidth;\r
+               pwlf->lfEscapement = v0->lpLogFont->lfEscapement;\r
+               pwlf->lfOrientation = v0->lpLogFont->lfOrientation;\r
+               pwlf->lfWeight = v0->lpLogFont->lfWeight;\r
+               pwlf->lfItalic = v0->lpLogFont->lfItalic;\r
+               pwlf->lfUnderline = v0->lpLogFont->lfUnderline;\r
+               pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;\r
+               pwlf->lfCharSet = v0->lpLogFont->lfCharSet;\r
+               pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;\r
+               pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;\r
+               pwlf->lfQuality = v0->lpLogFont->lfQuality;\r
+               pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;\r
+               MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);\r
+               TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);\r
+       }\r
+       else\r
+               pwlf = NULL;\r
+       a0.lpLogFont = pwlf;\r
+       a0.iPointSize = v0->iPointSize;\r
+       a0.Flags = v0->Flags;\r
+       a0.rgbColors = v0->rgbColors;\r
+       a0.lCustData = v0->lCustData;\r
+       a0.lpfnHook = v0->lpfnHook;\r
+       pw0 = DuplicateMtoW(v0->lpTemplateName, -1);\r
+       a0.lpTemplateName = pw0;\r
+       a0.hInstance = v0->hInstance;\r
+       pw1 = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);\r
+       a0.lpszStyle = pw1;\r
+       a0.nFontType = v0->nFontType;\r
+       a0.nSizeMin = v0->nSizeMin;\r
+       a0.nSizeMax = v0->nSizeMax;\r
+       r = ChooseFontW(&a0);\r
+       if(v0->lpLogFont)\r
+       {\r
+               v0->lpLogFont->lfHeight = pwlf->lfHeight;\r
+               v0->lpLogFont->lfWidth = pwlf->lfWidth;\r
+               v0->lpLogFont->lfEscapement = pwlf->lfEscapement;\r
+               v0->lpLogFont->lfOrientation = pwlf->lfOrientation;\r
+               v0->lpLogFont->lfWeight = pwlf->lfWeight;\r
+               v0->lpLogFont->lfItalic = pwlf->lfItalic;\r
+               v0->lpLogFont->lfUnderline = pwlf->lfUnderline;\r
+               v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;\r
+               v0->lpLogFont->lfCharSet = pwlf->lfCharSet;\r
+               v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;\r
+               v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;\r
+               v0->lpLogFont->lfQuality = pwlf->lfQuality;\r
+               v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;\r
+               WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);\r
+               TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);\r
+       }\r
+       v0->rgbColors = a0.rgbColors;\r
+       WtoM(v0->lpszStyle, LF_FACESIZE, pw1, -1);\r
+       TerminateStringM(v0->lpszStyle, LF_FACESIZE);\r
+       v0->nFontType = a0.nFontType;\r
+       if(pwlf)\r
+               free(pwlf);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
+{\r
+       INT_PTR r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpTemplateName, -1);\r
+       r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HWND CreateDialogParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
+{\r
+       HWND r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpTemplateName, -1);\r
+       r = CreateDialogParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL sndPlaySoundM(LPCSTR pszSound, UINT fuSound)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(pszSound, -1);\r
+       r = sndPlaySoundW(pw0, fuSound);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HANDLE SetClipboardDataM(UINT uFormat, HANDLE hMem)\r
+{\r
+       HANDLE r = NULL;\r
+       char* p;\r
+       int Length;\r
+       int BufferLength;\r
+       HGLOBAL hBufferMem;\r
+START_ROUTINE\r
+       if(uFormat == CF_TEXT)\r
+       {\r
+               p = (char*)GlobalLock(hMem);\r
+               Length = (int)GlobalSize(hMem);\r
+               BufferLength = MtoW(NULL, 0, p, Length);\r
+               if(hBufferMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * BufferLength))\r
+               {\r
+                       MtoW((LPWSTR)GlobalLock(hBufferMem), BufferLength, p, Length);\r
+                       GlobalUnlock(hBufferMem);\r
+                       r = SetClipboardData(CF_UNICODETEXT, hBufferMem);\r
+               }\r
+               GlobalUnlock(hMem);\r
+               GlobalFree(hMem);\r
+       }\r
+       else\r
+               r = SetClipboardData(uFormat, hMem);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
+       pw1 = DuplicateMtoW(lpNewFileName, -1);\r
+       r = CopyFileW(pw0, pw1, bFailIfExists);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+BOOL MoveFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
+       pw1 = DuplicateMtoW(lpNewFileName, -1);\r
+       r = MoveFileW(pw0, pw1);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+BOOL DeleteFileM(LPCSTR lpFileName)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = DeleteFileW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int mkdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wmkdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _mkdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wmkdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int rmdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wrmdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _rmdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wrmdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int removeM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wremove(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _removeM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wremove(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _unlinkM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wunlink(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+size_t _mbslenM(const unsigned char * _Str)\r
+{\r
+       size_t r = 0;\r
+START_ROUTINE\r
+       while(GetNextCharM(_Str, &_Str) > 0)\r
+       {\r
+               r++;\r
+       }\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+       unsigned char* r = NULL;\r
+       unsigned int c;\r
+       unsigned char* p;\r
+START_ROUTINE\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       {\r
+               if(c == _Ch)\r
+                       break;\r
+               _Str = p;\r
+       }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+       unsigned char* r = NULL;\r
+       unsigned int c;\r
+       unsigned char* p;\r
+START_ROUTINE\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       {\r
+               if(c == _Ch)\r
+                       r = (unsigned char*)_Str;\r
+               _Str = p;\r
+       }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = strstr(_Str, _Substr);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+       int r = 0;\r
+START_ROUTINE\r
+       r = strcmp(_Str1, _Str2);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+       int r = 0;\r
+START_ROUTINE\r
+       r = _stricmp(_Str1, _Str2);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
+{\r
+       int r = 0;\r
+       DWORD c1;\r
+       DWORD c2;\r
+START_ROUTINE\r
+       c1 = 0;\r
+       c2 = 0;\r
+       while(_MaxCount > 0)\r
+       {\r
+               c1 = GetNextCharM(_Str1, &_Str1);\r
+               c2 = GetNextCharM(_Str2, &_Str2);\r
+               if(c1 != c2)\r
+                       break;\r
+               _MaxCount--;\r
+               if(c1 == 0 || c2 == 0)\r
+                       break;\r
+       }\r
+       r = c1 - c2;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbslwrM(unsigned char * _String)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = _strlwr(_String);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsuprM(unsigned char * _String)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = _strupr(_String);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
+       {\r
+               _Count--;\r
+       }\r
+       r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+FILE * fopenM(const char * _Filename, const char * _Mode)\r
+{\r
+       FILE* r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       pw1 = DuplicateMtoW(_Mode, -1);\r
+       r = _wfopen(pw0, pw1);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r