-
o
-
-
C`bg
-
ANZX
第2弾 ---- GRsock (GameReader over Winsock)
Fedoraでの画面(第1弾も第2弾も同じような画面ですが、MSXGr.dllの内容は異なります)
今回は一応、本物のMSXゲームリーダーを使います。ただし、MSXPLAYerを実行する仮想PCとゲームリーダーのデバイスドライバをインストールした仮想PCは別です。
MSXPLAYerが使用するMSXGr.dllは偽物で、ここから別PCと通信します。別PCのEXEファイルが本物のMSXGr.dllを使用してゲームリーダーを制御します。
LinuxでWineを利用してMSXPLAYerを実行した例を図で表現すると、こんな感じです。
XPのほうでは、こんな感じでEXEファイルを動作させています。
コマンドプロンプトです。フルスクリーンにしてもしなくても良いです。
同時に接続できるのは1つのクライアントだけです。
DLLファイルもEXEファイルも配布しません。C言語のソースの一部分だけ置いておきます。
GRsock_client_include.h と GRsock_server_include.h の中に、適切な内容を記入してください。GRsock_client.c, GRsock_server.c, GRsock_common.h はこのままで動作するはずです。
C言語 GRsock_client.c
/* ----------------------------------------------------------------------- file: GRsock_client.c version: 0.0.0.x (2020/02/23) description: This is a source file of fake "MSXGr.dll". I don't decide the license of this file yet. Copyright 2020 umaiboux ----------------------------------------------------------------------- */ #define WIN32_LEAN_AND_MEAN #include
#include
#include
#include "GRsock_common.h" #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") #if defined(__cplusplus) #define DEF_ENTRY extern "C" #else #define DEF_ENTRY #endif char sbuf[0x10000 + 16]; char rbuf[4]; /*#define ENABLE_OUTLOG*/ #ifdef ENABLE_OUTLOG #include
#define OUTLOG(s, ...) {sprintf(outlogbuf, s, __VA_ARGS__);outlogf();} void outlogf(void); char outlogbuf[65536]; void outlogf(void) { HANDLE hFile; DWORD dwBytesWritten; hFile = CreateFile("GRsock_client.log", FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return; } /* needed lock? https://docs.microsoft.com/ja-jp/windows/win32/fileio/appending-one-file-to-another-file */ if (WriteFile( hFile, outlogbuf, strlen(outlogbuf), &dwBytesWritten, NULL)) { } CloseHandle(hFile); } #else #define OUTLOG(s, ...) #endif #if !defined(_WIN32) || defined(_WIN64) #error "not 32bit" #endif SOCKET ConnectSocket = INVALID_SOCKET; int WS_Init(void) { #include "GRsock_client_include.h" { BOOL val = TRUE; setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(val)); } return 0; } int WS_Uninit(void) { closesocket(ConnectSocket); WSACleanup(); return 0; } void WS_SetParam(int index, int value) { *((int*)sbuf + (index+1)) = value; } void WS_SetParamPtr(int index, char *pBuffer, int len) { CopyMemory(sbuf + ((index+1)*4), pBuffer, len); } int WS_Send(int cmd, int len) { int iResult; *((int*)sbuf) = cmd; iResult = send( ConnectSocket, sbuf, len+4, 0 ); if (iResult == SOCKET_ERROR) { OUTLOG("WS_Send error: %d\n", WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return 1; } return 0; } int WS_RecvPtr(int len, char *pBuffer) { int iResult; int cnt = 0; for(;0
0 ) { } else if ( iResult == 0 ) { OUTLOG("Connection closed\n"); return -1; } else { OUTLOG("WS_RecvPtr error: %d\n", WSAGetLastError()); return -1; } if (( iResult != len ) || (cnt)) { /*OUTLOG("WS_RecvPtr iResult: %d len: %d cnt: %d\n", iResult, len, cnt);*/ } len -= iResult; pBuffer += iResult; cnt++; } return 0; } int WS_Recv(int len) { return WS_RecvPtr(len, rbuf); } int WS_GetParam(void) { return *((int*)rbuf); } #if defined(__BORLANDC__) BOOL APIENTRY DllEntryPoint( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) #else BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) #endif { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: break; } return TRUE; } /* __declspec(dllexport) typedef int (__cdecl *_MSXGR_Init)(); typedef void (__cdecl *_MSXGR_Uninit)(); typedef char* (__cdecl *_MSXGR_Err2Str)(int); typedef int (__cdecl *_MSXGR_GetVersion)(); typedef void (__cdecl *_MSXGR_SetDebugMode)(int); typedef bool (__cdecl *_MSXGR_IsSlotEnable)(int); typedef int (__cdecl *_MSXGR_GetSlotStatus)(int,int*); typedef int (__cdecl *_MSXGR_ReadMemory)(int,char*,int,int); typedef int (__cdecl *_MSXGR_WriteMemory)(int,char*,int,int); typedef int (__cdecl *_MSXGR_ReadIO)(int,char*,int,int); typedef int (__cdecl *_MSXGR_WriteIO)(int,char*,int,int); typedef int (__cdecl *_MSXGR_SetEventNotification)(int); */ DEF_ENTRY __declspec(dllexport) int MSXGR_Init(void); DEF_ENTRY __declspec(dllexport) void MSXGR_Uninit(void); DEF_ENTRY __declspec(dllexport) char* MSXGR_Err2Str(int); DEF_ENTRY __declspec(dllexport) int MSXGR_GetVersion(void); DEF_ENTRY __declspec(dllexport) void MSXGR_SetDebugMode(int); DEF_ENTRY __declspec(dllexport) DEF_bool MSXGR_IsSlotEnable(int); DEF_ENTRY __declspec(dllexport) int MSXGR_GetSlotStatus(int,int*); DEF_ENTRY __declspec(dllexport) int MSXGR_ReadMemory(int,char*,int,int); DEF_ENTRY __declspec(dllexport) int MSXGR_WriteMemory(int,char*,int,int); DEF_ENTRY __declspec(dllexport) int MSXGR_ReadIO(int,char*,int,int); DEF_ENTRY __declspec(dllexport) int MSXGR_WriteIO(int,char*,int,int); DEF_ENTRY __declspec(dllexport) int MSXGR_SetEventNotification(int); int MSXGR_Init(void) { OUTLOG("MSXGR_Init LINE %d\n", __LINE__); if (WS_Init()) return 1; if (WS_Send(GRCMD_Init, 0)) return 1; if (WS_Recv(4)) return 1; OUTLOG("MSXGR_Init LINE %d param %d\n", __LINE__, WS_GetParam()); return WS_GetParam(); } void MSXGR_Uninit(void) { WS_Send(GRCMD_Uninit, 0); WS_Uninit(); } char* MSXGR_Err2Str(int nError) { /* Todo: - send command over Winsock - recv strings over Winsock - do not free memory immediately - do not reuse memory immediately */ return "MSXGR_Err2Str is dummy"; } int MSXGR_GetVersion(void) { if (WS_Send(GRCMD_GetVersion, 0)) return 1; if (WS_Recv(4)) return 1; return WS_GetParam(); } void MSXGR_SetDebugMode(int nLevel) { WS_SetParam(0, nLevel); WS_Send(GRCMD_SetDebugMode, 4); } DEF_bool MSXGR_IsSlotEnable(int nSlot) { WS_SetParam(0, nSlot); WS_Send(GRCMD_IsSlotEnable, 4); if (WS_Recv(4)) return 1; OUTLOG("MSXGR_IsSlotEnable LINE %d param %d\n", __LINE__, WS_GetParam()); return (DEF_bool)WS_GetParam(); } int MSXGR_GetSlotStatus(int nSlot,int *pBuffer) { int iResult; WS_SetParam(0, nSlot); WS_Send(GRCMD_GetSlotStatus, 4); if (WS_Recv(4)) return 1; iResult = WS_GetParam(); if (WS_RecvPtr(12, (char*)pBuffer)) return 1; OUTLOG("MSXGR_GetSlotStatus LINE %d iResult %d Buffer0 %x Buffer1 %x Buffer2 %x\n", __LINE__, iResult, pBuffer[0], pBuffer[1], pBuffer[2]); return iResult; } int MSXGR_ReadMemory(int nSlot,char* pBuffer,int nAddress,int nLength) { int iResult; if (nLength > 0x10000) nLength = 0x10000; else if (nLength < 0) nLength = 0; WS_SetParam(0, nSlot); WS_SetParam(1, nAddress); WS_SetParam(2, nLength); WS_Send(GRCMD_ReadMemory, 12); if (WS_Recv(4)) return 1; iResult = WS_GetParam(); if (WS_RecvPtr(nLength, pBuffer)) return 1; return iResult; } int MSXGR_WriteMemory(int nSlot,char* pBuffer,int nAddress,int nLength) { if (nLength > 0x10000) nLength = 0x10000; else if (nLength < 0) nLength = 0; WS_SetParam(0, nSlot); WS_SetParam(1, nAddress); WS_SetParam(2, nLength); WS_SetParamPtr(3, pBuffer, nLength); WS_Send(GRCMD_WriteMemory, 12 + nLength); if (WS_Recv(4)) return 1; return WS_GetParam(); } int MSXGR_ReadIO(int nSlot,char* pBuffer,int nAddress,int nLength) { int iResult; if (nLength > 0x10000) nLength = 0x10000; else if (nLength < 0) nLength = 0; WS_SetParam(0, nSlot); WS_SetParam(1, nAddress); WS_SetParam(2, nLength); WS_Send(GRCMD_ReadIO, 12); if (WS_Recv(4)) return 1; iResult = WS_GetParam(); if (WS_RecvPtr(nLength, pBuffer)) return 1; return iResult; } int MSXGR_WriteIO(int nSlot,char* pBuffer,int nAddress,int nLength) { if (nLength > 0x10000) nLength = 0x10000; else if (nLength < 0) nLength = 0; WS_SetParam(0, nSlot); WS_SetParam(1, nAddress); WS_SetParam(2, nLength); WS_SetParamPtr(3, pBuffer, nLength); WS_Send(GRCMD_WriteIO, 12 + nLength); if (WS_Recv(4)) return 1; return WS_GetParam(); } int MSXGR_SetEventNotification(int dummy) { WS_SetParam(0, dummy); if (WS_Send(GRCMD_SetEventNotification, 4)) return 1; if (WS_Recv(4)) return 1; return WS_GetParam(); }
C言語 GRsock_server.c
/* ----------------------------------------------------------------------- file: GRsock_server.c version: 0.0.0.x (2020/02/23) description: This is a source file of "GRsock_server.exe". I don't decide the license of this file yet. Copyright 2020 umaiboux ----------------------------------------------------------------------- */ #define WIN32_LEAN_AND_MEAN #include
#include
#include
#include
#include
#include "GRsock_common.h" #pragma comment (lib, "Ws2_32.lib") HINSTANCE hDll = NULL; #if !defined(_WIN32) || defined(_WIN64) #error "not 32bit" #endif /* __declspec(dllexport) */ typedef int (__cdecl *_MSXGR_Init)(void); typedef void (__cdecl *_MSXGR_Uninit)(void); typedef char* (__cdecl *_MSXGR_Err2Str)(int); typedef int (__cdecl *_MSXGR_GetVersion)(void); typedef void (__cdecl *_MSXGR_SetDebugMode)(int); typedef DEF_bool (__cdecl *_MSXGR_IsSlotEnable)(int); typedef int (__cdecl *_MSXGR_GetSlotStatus)(int,int*); typedef int (__cdecl *_MSXGR_ReadMemory)(int,char*,int,int); typedef int (__cdecl *_MSXGR_WriteMemory)(int,char*,int,int); typedef int (__cdecl *_MSXGR_ReadIO)(int,char*,int,int); typedef int (__cdecl *_MSXGR_WriteIO)(int,char*,int,int); typedef int (__cdecl *_MSXGR_SetEventNotification)(int); _MSXGR_Err2Str tMSXGR_Err2Str; _MSXGR_GetVersion tMSXGR_GetVersion; _MSXGR_SetDebugMode tMSXGR_SetDebugMode; _MSXGR_IsSlotEnable tMSXGR_IsSlotEnable; _MSXGR_GetSlotStatus tMSXGR_GetSlotStatus; _MSXGR_ReadMemory tMSXGR_ReadMemory; _MSXGR_WriteMemory tMSXGR_WriteMemory; _MSXGR_WriteIO tMSXGR_WriteIO; _MSXGR_ReadIO tMSXGR_ReadIO; _MSXGR_SetEventNotification tMSXGR_SetEventNotification; int MSXGR_Init(void); int MSXGR_Uninit(void); int MSXGR_Err2Str(void); int MSXGR_GetVersion(void); int MSXGR_SetDebugMode(void); int MSXGR_IsSlotEnable(void); int MSXGR_GetSlotStatus(void); int MSXGR_ReadMemory(void); int MSXGR_WriteMemory(void); int MSXGR_ReadIO(void); int MSXGR_WriteIO(void); int MSXGR_SetEventNotification(void); char sbuf[0x10000 + 4]; char rbuf[0x10000 + 16]; SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; DEF_bool bIsSlotEnableRetryDone; int iIsSlotEnableRetryNum; void WS_SetParam(int index, int value) { *((int*)sbuf + index) = value; } int WS_Send(int len) { int iResult; iResult = send( ClientSocket, sbuf, len, 0 ); if (iResult == SOCKET_ERROR) { printf("WS_Send error: %d\n", WSAGetLastError()); return 1; } return 0; } int WS_RecvPtr(int len, char *pBuffer) { int iResult; int cnt = 0; for(;0
0 ) { } else if ( iResult == 0 ) { printf("Connection closed\n"); return -1; } else { printf("WS_RecvPtr error: %d\n", WSAGetLastError()); return -1; } if (( iResult != len ) || (cnt)) { /*printf("WS_RecvPtr iResult: %d len: %d cnt: %d\n", iResult, len, cnt);*/ } len -= iResult; pBuffer += iResult; cnt++; } return 0; } int WS_Recv(int len) { return WS_RecvPtr(len, rbuf); } int WS_GetParam(int index) { return *((int*)rbuf + index); } int mainloop(void) { int iResult; int iSendResult; struct addrinfo *result = NULL; struct addrinfo hints; while(1) { #include "GRsock_server_include.h" { BOOL val = TRUE; setsockopt(ClientSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(val)); } do { int cmd; if (WS_Recv(4)) break; cmd = WS_GetParam(0); /* printf("recv cmd: %d\n", cmd);*/ switch (cmd) { case GRCMD_Init: iResult = MSXGR_Init(); break; case GRCMD_Uninit: iResult = MSXGR_Uninit(); break; case GRCMD_Err2Str: iResult = MSXGR_Uninit(); break; case GRCMD_GetVersion: iResult = MSXGR_GetVersion(); break; case GRCMD_SetDebugMode: iResult = MSXGR_SetDebugMode(); break; case GRCMD_IsSlotEnable: iResult = MSXGR_IsSlotEnable(); break; case GRCMD_GetSlotStatus: iResult = MSXGR_GetSlotStatus(); break; case GRCMD_ReadMemory: iResult = MSXGR_ReadMemory(); break; case GRCMD_WriteMemory: iResult = MSXGR_WriteMemory(); break; case GRCMD_ReadIO: iResult = MSXGR_ReadIO(); break; case GRCMD_WriteIO: iResult = MSXGR_WriteIO(); break; case GRCMD_SetEventNotification: iResult = MSXGR_SetEventNotification(); break; default: printf("recv cmd: %d\n", cmd); iResult = -1; break; } if (iResult) break; } while (1); closesocket(ClientSocket); } } int main(int ac, char *av[]) { WSADATA wsaData; int iResult; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup error: %d\n", iResult); return 1; } if (ac < 2) { iIsSlotEnableRetryNum = 0; } else { iIsSlotEnableRetryNum = atoi(av[1]); } mainloop(); WSACleanup(); return 0; } int MSXGR_Init(void) { _MSXGR_Init tMSXGR_Init; int iResult; bIsSlotEnableRetryDone = DEF_false; printf("trying LoadLibrary and GetProcAddress...\n"); do { hDll = LoadLibrary("MSXGr.dll"); if (hDll == NULL) { iResult = DEF_ERR1; break; } tMSXGR_Init = (_MSXGR_Init)GetProcAddress(hDll, "MSXGR_Init"); if (tMSXGR_Init == NULL) { iResult = -1; break; } iResult = tMSXGR_Init(); if (iResult) { FreeLibrary(hDll); hDll = NULL; break; } tMSXGR_Err2Str = (_MSXGR_Err2Str)GetProcAddress(hDll, "MSXGR_Err2Str"); tMSXGR_GetVersion = (_MSXGR_GetVersion)GetProcAddress(hDll, "MSXGR_GetVersion"); tMSXGR_SetDebugMode = (_MSXGR_SetDebugMode)GetProcAddress(hDll, "MSXGR_SetDebugMode"); tMSXGR_IsSlotEnable = (_MSXGR_IsSlotEnable)GetProcAddress(hDll, "MSXGR_IsSlotEnable"); tMSXGR_GetSlotStatus = (_MSXGR_GetSlotStatus)GetProcAddress(hDll, "MSXGR_GetSlotStatus"); tMSXGR_ReadMemory = (_MSXGR_ReadMemory)GetProcAddress(hDll, "MSXGR_ReadMemory"); tMSXGR_WriteMemory = (_MSXGR_WriteMemory)GetProcAddress(hDll, "MSXGR_WriteMemory"); tMSXGR_WriteIO = (_MSXGR_WriteIO)GetProcAddress(hDll, "MSXGR_WriteIO"); tMSXGR_ReadIO = (_MSXGR_ReadIO)GetProcAddress(hDll, "MSXGR_ReadIO"); iResult = 0; printf("OK: LoadLibrary and GetProcAddress\n"); } while(0); WS_SetParam(0, iResult); printf("MSXGR_Init ret %d\n", iResult); return WS_Send(4); } int MSXGR_Uninit(void) { _MSXGR_Uninit tMSXGR_Uninit; bIsSlotEnableRetryDone = DEF_false; printf("MSXGR_Uninit\n"); if (!hDll) { return 0; } tMSXGR_Uninit = (_MSXGR_Uninit)GetProcAddress(hDll, "MSXGR_Uninit"); if (tMSXGR_Uninit) { tMSXGR_Uninit(); } FreeLibrary(hDll); hDll = NULL; return 0; } int MSXGR_Err2Str(void) { int nError; char* p; if (WS_Recv(4)) return 1; nError = WS_GetParam(0); p = tMSXGR_Err2Str(nError); /* Todo: - send strings over Winsock */ return 0; } int MSXGR_GetVersion(void) { WS_SetParam(0, tMSXGR_GetVersion()); return WS_Send(4); } int MSXGR_SetDebugMode(void) { int nLevel; if (WS_Recv(4)) return 1; nLevel = WS_GetParam(0); tMSXGR_SetDebugMode(nLevel); return 0; } int MSXGR_IsSlotEnable(void) { int nSlot; DEF_bool bRet; if (WS_Recv(4)) return 1; nSlot = WS_GetParam(0); bRet = tMSXGR_IsSlotEnable(nSlot); printf("MSXGR_IsSlotEnable Slot %d ret %d\n", nSlot, (int)bRet); if (!bRet && !bIsSlotEnableRetryDone) { int iResult; int loop1, loop2; bIsSlotEnableRetryDone = DEF_true; for(loop1=0; loop1
C言語 GRsock_common.h
#define DEFAULT_PORT "37016" #define DEF_false 0 #define DEF_true 1 #define DEF_bool char #define DEF_ERR1 1 #define GRCMD_Init 0 #define GRCMD_Uninit 1 #define GRCMD_Err2Str 2 #define GRCMD_GetVersion 3 #define GRCMD_SetDebugMode 4 #define GRCMD_IsSlotEnable 5 #define GRCMD_GetSlotStatus 6 #define GRCMD_ReadMemory 7 #define GRCMD_WriteMemory 8 #define GRCMD_ReadIO 9 #define GRCMD_WriteIO 10 #define GRCMD_SetEventNotification 11
C言語 GRsock_client_include.h
Please write appropriate code here. See: https://docs.microsoft.com/ja-jp/windows/win32/winsock/complete-client-code WSAStartup(...); ConnectSocket = socket(...); connect( ConnectSocket,...); if(any_error) return 1;
C言語 GRsock_server_include.h
Please write appropriate code here. See: https://docs.microsoft.com/ja-jp/windows/win32/winsock/complete-server-code ListenSocket = socket(...); bind(...) listen(...) ClientSocket = accept(ListenSocket, ...); if(any_error) {closesocket, return 1;} closesocket(ListenSocket);
戻る
ANZX
SEO
/
SEO
FC2
:
Text
AD
:
JEFFC2
z[y[W
T[rXLO
VbsOJ[g
BBS
Cu`bg
JE^[
[
hCo^798~`
^T[o[
AvP[VJ
Io