/xliveless.cpp

https://bitbucket.org/zabb65/xliveless-dirt3 · C++ · 1303 lines · 932 code · 190 blank · 181 comment · 104 complexity · 0939c8ba7bb9df41c9cec7e4db0e86fb MD5 · raw file

  1. // -No Copyright- 2010 Stanislav "listener" Golovin
  2. // This file donated to the public domain
  3. #include "stdafx.h"
  4. typedef ULONGLONG XUID;
  5. typedef XUID *PXUID;
  6. typedef struct {
  7. WORD wActionId;
  8. WCHAR wszActionText[23];
  9. DWORD dwFlags;
  10. }XCUSTOMACTION;
  11. typedef
  12. VOID
  13. (WINAPI *PXOVERLAPPED_COMPLETION_ROUTINE)(
  14. __in DWORD dwErrorCode,
  15. __in DWORD dwNumberOfBytesTransfered,
  16. __inout struct _XOVERLAPPED* pOverlapped);
  17. typedef struct _XOVERLAPPED {
  18. ULONG_PTR InternalLow;
  19. ULONG_PTR InternalHigh;
  20. ULONG_PTR InternalContext;
  21. HANDLE hEvent;
  22. PXOVERLAPPED_COMPLETION_ROUTINE pCompletionRoutine;
  23. DWORD_PTR dwCompletionContext;
  24. DWORD dwExtendedError;
  25. }XOVERLAPPED, *PXOVERLAPPED;
  26. #ifndef NO_TRACE
  27. CRITICAL_SECTION d_lock;
  28. static FILE * logfile;
  29. XLIVELESS_API void trace (char * message, ...) {
  30. if (!logfile)
  31. return;
  32. EnterCriticalSection (&d_lock);
  33. if (!logfile)
  34. return;
  35. SYSTEMTIME t;
  36. GetLocalTime (&t);
  37. fprintf (logfile, "%02d/%02d/%04d %02d:%02d:%02d.%03d ", t.wDay, t.wMonth, t.wYear, t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);
  38. va_list arg;
  39. va_start (arg, message);
  40. vfprintf (logfile, message, arg);
  41. fflush (logfile);
  42. va_end (arg);
  43. LeaveCriticalSection (&d_lock);
  44. }
  45. #else
  46. #undef trace
  47. #define trace(message, ...)
  48. #endif
  49. XLIVELESS_API GameVersion dwGameVersion = GvUnknown;
  50. XLIVELESS_API DWORD dwLoadOffset = 0x400000;
  51. // Delphi don't support importing variables from DLL
  52. XLIVELESS_API GameVersion getGameVersion () { return dwGameVersion; }
  53. XLIVELESS_API DWORD getLoadOffset () { return dwLoadOffset; }
  54. XLIVELESS_API void injectFunction (DWORD dwAddress, DWORD pfnReplacement) {
  55. dwAddress += dwLoadOffset;
  56. BYTE * patch = (BYTE *)dwAddress;
  57. *patch = 0xE9; // JMP
  58. *(DWORD *)(patch+1) = (pfnReplacement-(dwAddress+5));
  59. }
  60. // === Start of xlive functions ===
  61. // TODO: move all GfWL functions to the separate file
  62. // #1: XWSAStartup
  63. extern "C" int __stdcall XWSAStartup (WORD wVersionRequested, LPWSADATA lpWsaData) {
  64. lpWsaData->wVersion = 2;
  65. trace ("XWSAStartup \n");
  66. return 0;
  67. }
  68. // #2: XWSACleanup
  69. extern "C" void __stdcall XWSACleanup () { // XWSACleanup
  70. trace ("XWSACleanup\n");
  71. }
  72. // #3: XCreateSocket
  73. extern "C" SOCKET __stdcall XCreateSocket (int af, int type, int protocol) {
  74. trace ("XCreateSocket (%d, %d, %d)\n", af, type, protocol);
  75. return INVALID_SOCKET;
  76. }
  77. // #4: XSockeClose
  78. extern "C" int __stdcall XSockeClose (SOCKET s) {
  79. trace ("XSockeClose)\n");
  80. return 0;
  81. }
  82. // #5: XSocketShutdown
  83. extern "C" int __stdcall XSocketShutdown (SOCKET s, int how) {
  84. trace ("XSocketShutdown\n");
  85. return 0;
  86. }
  87. // #6: XSocketIOCTLSocket
  88. extern "C" int __stdcall XSocketIOCTLSocket (SOCKET s, long cmd, long * argp) {
  89. trace ("XSocketIOCTLSocket\n");
  90. return 0;
  91. }
  92. // #7: XSocketSetSockOpt
  93. extern "C" int __stdcall XSocketSetSockOpt (SOCKET s, DWORD, DWORD, DWORD, DWORD) {
  94. trace ("XSocketSetSockOpt\n");
  95. return 0;
  96. }
  97. // #9: XSocketGetSockName
  98. extern "C" int __stdcall XSocketGetSockName (SOCKET s, sockaddr_in * name, int * namelen) {
  99. trace ("XSocketGetSockName\n");
  100. if (namelen && name && *namelen == sizeof (sockaddr_in))
  101. memset (name, 0, sizeof (sockaddr_in));
  102. return 0;
  103. }
  104. // #11: XSocketBind
  105. extern "C" SOCKET __stdcall XSocketBind (SOCKET s, sockaddr_in * addr, int * addrlen) {
  106. trace ("XSocketBind\n");
  107. return INVALID_SOCKET;
  108. }
  109. // #12: XSocketConnect
  110. extern "C" int __stdcall XSocketConnect (SOCKET s, sockaddr_in * addr, int * addrlen) {
  111. trace ("XSocketConnect\n");
  112. return 0;
  113. }
  114. // #13: XSocketListen
  115. extern "C" int __stdcall XSocketListen (SOCKET s, int backlog) {
  116. trace ("XSocketListen\n");
  117. return 0;
  118. }
  119. // #14: XSocketAccept
  120. extern "C" SOCKET __stdcall XSocketAccept (SOCKET s, sockaddr_in * addr, int * addrlen) {
  121. trace ("XSocketAccept\n");
  122. return INVALID_SOCKET;
  123. }
  124. // #15: XSocketSelect
  125. extern "C" int __stdcall XSocketSelect (int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout) {
  126. trace ("XSocketSelect\n");
  127. return 0;
  128. }
  129. // #18: XSocketRecv
  130. extern "C" int __stdcall XSocketRecv (SOCKET s, char * buf, int len, int flags) {
  131. return 0;
  132. }
  133. // #20: XSocketRecvFrom
  134. extern "C" int __stdcall XSocketRecvFrom (SOCKET s, char * buf, int len, int flags, sockaddr_in * from, int fromlen) {
  135. return 0;
  136. }
  137. // #22: XSocketSend
  138. extern "C" int __stdcall XSocketSend (SOCKET s, char * buf, int len, int flags) {
  139. return 0;
  140. }
  141. // #24: XSocketSendTo
  142. extern "C" int __stdcall XSocketSendTo (SOCKET s, char * buf, int len, int flags, sockaddr_in * to, int tolen) {
  143. return 0;
  144. }
  145. // #26: XSocketInet_Addr
  146. extern "C" int __stdcall XSocketInet_Addr (char *) {
  147. trace ("XSocketInet_Addr\n");
  148. return 0;
  149. }
  150. // #27: XWSAGetLastError
  151. extern "C" int __stdcall XWSAGetLastError () {
  152. return WSAENETDOWN; // 0 ?
  153. }
  154. // #37 XSocketHTONL
  155. extern "C" DWORD __stdcall XSocketHTONL (DWORD n) {
  156. return ((n&0xFF000000) >> 24)|((n & 0x00FF0000) >> 8)|((n&0x0000FF00) << 8)|((n & 0x000000FF) << 24);
  157. //return htonl(n);
  158. }
  159. // #38: XSocketNTOHS
  160. extern "C" WORD __stdcall XSocketNTOHS (WORD n) {
  161. //return ntohs(n);
  162. return ((n&0xFF00) >> 8)|((n&0xFF) << 8);
  163. }
  164. // #39: XSocketNTOHL
  165. extern "C" DWORD __stdcall XSocketNTOHL (DWORD n) {
  166. //return ntohl(n);
  167. return ((n&0xFF000000) >> 24)|((n & 0x00FF0000) >> 8)|((n&0x0000FF00) << 8)|((n & 0x000000FF) << 24);
  168. }
  169. // #40 XSocketHTONS
  170. extern "C" WORD __stdcall XSocketHTONS (WORD n) {
  171. return ((n&0xFF00) >> 8)|((n&0xFF) << 8);
  172. //return htons(n);
  173. }
  174. // #51: XNetStartup
  175. extern "C" int __stdcall XNetStartup (void *) { // XNetStartup(XNetStartupParams *)
  176. trace ("XNetStartup\n");
  177. return 0;
  178. }
  179. // #52: XNetCleanup
  180. extern "C" int __stdcall XNetCleanup () {
  181. trace ("xlive_52: XNetCleanup\n");
  182. return 0;
  183. }
  184. // #54: XNetCreateKey
  185. extern "C" int __stdcall XNetCreateKey (void * pxnkid, void * pxnkey) {
  186. trace ("XNetCreateKey\n");
  187. return 0;
  188. }
  189. // #55: XNetRegisterKey
  190. extern "C" int __stdcall XNetRegisterKey (DWORD, DWORD) {
  191. return 0;
  192. }
  193. // #56: XNetUnregisterKey
  194. extern "C" int __stdcall XNetUnregisterKey (DWORD) {
  195. return 0;
  196. }
  197. // #57: XNetXnAddrToInAddr
  198. extern "C" int __stdcall XNetXnAddrToInAddr (DWORD, DWORD, DWORD * p) {
  199. *p = 0;
  200. return 0;
  201. }
  202. // #58: XNetServerToInAddr
  203. extern "C" DWORD __stdcall XNetServerToInAddr (DWORD, DWORD, DWORD) {
  204. return 0;
  205. }
  206. // #60: XNetInAddrToXnAddr
  207. extern "C" DWORD __stdcall XNetInAddrToXnAddr (DWORD, DWORD, DWORD) {
  208. return 0;
  209. }
  210. // #63: XNetUnregisterInAddr
  211. extern "C" int __stdcall XNetUnregisterInAddr (DWORD) {
  212. return 0;
  213. }
  214. // #64: XNetXnAddrToMachineId
  215. extern "C" DWORD __stdcall XNetXnAddrToMachineId (DWORD, ULONGLONG* out) {
  216. *out = 0ULL;
  217. return 0;
  218. }
  219. // #65: XNetConnect
  220. extern "C" int __stdcall XNetConnect (DWORD) {
  221. return 0;
  222. }
  223. // #66: XNetGetConnectStatus
  224. extern "C" int __stdcall XNetGetConnectStatus (DWORD) {
  225. trace ("XNetGetConnectStatus\n");
  226. return 0;
  227. }
  228. // #69: XNetQosListen
  229. extern "C" DWORD __stdcall XNetQosListen (DWORD, DWORD, DWORD, DWORD, DWORD) {
  230. return 0;
  231. }
  232. // #70: XNetQosLookup
  233. extern "C" DWORD __stdcall XNetQosLookup (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  234. return 0;
  235. }
  236. // #71: XNetQosServiceLookup
  237. extern "C" DWORD __stdcall XNetQosServiceLookup (DWORD, DWORD, DWORD) {
  238. return 0;
  239. }
  240. // #72: XNetQosRelease
  241. extern "C" DWORD __stdcall XNetQosRelease (DWORD) {
  242. return 0;
  243. }
  244. // #73: XNetGetTitleXnAddr
  245. extern "C" DWORD __stdcall XNetGetTitleXnAddr (DWORD * pAddr) {
  246. *pAddr = 0x0100007F; // 127.0.0.1
  247. return 4;
  248. }
  249. // #75: XNetGetEthernetLinkStatus
  250. extern "C" DWORD __stdcall XNetGetEthernetLinkStatus () {
  251. return 1;
  252. }
  253. // #84: XNetSetSystemLinkPort
  254. extern "C" DWORD __stdcall XNetSetSystemLinkPort (DWORD) {
  255. return 0;
  256. }
  257. // #473: XCustomGetLastActionPress
  258. extern "C" int __stdcall XCustomGetLastActionPress (DWORD, DWORD, DWORD) {
  259. trace ("XCustomGetLastActionPress\n");
  260. return 0;
  261. }
  262. extern "C" DWORD __stdcall XCustomGetLastActionPressEx (DWORD*, DWORD*, XUID*, WORD*) {
  263. trace ("XCustomGetLastActionPressEx\n");
  264. return ERROR_NO_DATA;
  265. }
  266. // #651: XNotifyGetNext
  267. extern "C" int __stdcall XNotifyGetNext (HANDLE hNotification, DWORD dwMsgFilter, DWORD * pdwId, void * pParam) {
  268. return 0; // no notifications
  269. }
  270. // #652: XNotifyPositionUI
  271. extern "C" DWORD __stdcall XNotifyPositionUI (DWORD dwPosition) {
  272. trace ("XNotifyPositionUI (%d)\n", dwPosition);
  273. return 0;
  274. }
  275. // #1082: XGetOverlappedExtendedError
  276. extern "C" DWORD __stdcall XGetOverlappedExtendedError (void *) {
  277. trace ("XGetOverlappedExtendedError\n");
  278. return 0;
  279. }
  280. // #1083: XGetOverlappedResult
  281. extern "C" DWORD __stdcall XGetOverlappedResult (PXOVERLAPPED buffer, DWORD* pResult, DWORD bWait) {
  282. trace ("XGetOverlappedResult(%p, %p, %x)\n", buffer, pResult, bWait);
  283. if(!buffer)
  284. return ERROR_INVALID_PARAMETER;
  285. trace ("XGetOverlappedResult(): InternalLow: %x InternalHigh: %x InternalContext: %x, hEvent: %x CompletionRoutine: %p CompletionContext: %p ExtendedError: %x\n",
  286. buffer->InternalLow, buffer->InternalHigh, buffer->InternalContext, buffer->hEvent, buffer->pCompletionRoutine, buffer->dwCompletionContext, buffer->dwExtendedError);
  287. if(buffer->InternalLow == 0xC0DEBEEF)
  288. *pResult = buffer->InternalHigh;
  289. return 0;
  290. }
  291. // #5000: XLiveInitialize
  292. extern "C" int __stdcall XLiveInitialize (DWORD) { // XLiveInitialize(struct _XLIVE_INITIALIZE_INFO *)
  293. trace ("XLiveInitialize\n");
  294. return 0;
  295. }
  296. // #5001: XLiveInput
  297. extern "C" int __stdcall XLiveInput (DWORD * p) {
  298. // trace ("XLiveInput\n");
  299. p[5] = 0;
  300. return 1; // -1 ?
  301. }
  302. // #5002: XLiveRender
  303. extern "C" int __stdcall XLiveRender () {
  304. // trace ("XLiveRender\n");
  305. return 0;
  306. }
  307. // #5003: XLiveUninitialize
  308. extern "C" int __stdcall XLiveUninitialize () {
  309. trace ("XLiveUninitialize\n");
  310. return 0;
  311. }
  312. // #5005: XLiveOnCreateDevice
  313. extern "C" int __stdcall XLiveOnCreateDevice (DWORD, DWORD) {
  314. trace ("XLiveOnCreateDevice\n");
  315. return 0;
  316. }
  317. extern "C" DWORD __stdcall xlive_5006 () {
  318. trace ("xlive_5006\n");
  319. return 0;
  320. }
  321. // #5007: XLiveOnResetDevice
  322. extern "C" int __stdcall XLiveOnResetDevice (DWORD) {
  323. trace ("XLiveOnResetDevice\n");
  324. return 0;
  325. }
  326. // #5008: XHVCreateEngine
  327. extern "C" int __stdcall XHVCreateEngine (DWORD, DWORD, void ** ppEngine) {
  328. trace ("XHVCreateEngine\n");
  329. if (ppEngine)
  330. *ppEngine = NULL;
  331. return -1; // disable live voice
  332. }
  333. // #5022: XLiveGetUpdateInformation
  334. extern "C" int __stdcall XLiveGetUpdateInformation (DWORD) {
  335. trace ("XLiveGetUpdateInformation\n");
  336. return -1; // no update
  337. }
  338. // #5024: XLiveUpdateSystem
  339. extern "C" int __stdcall XLiveUpdateSystem (DWORD) {
  340. trace ("XLiveUpdateSystem\n");
  341. return -1; // no update
  342. }
  343. // #5028
  344. extern "C" DWORD __stdcall XLiveSecureLoadLibraryW (LPCWSTR path, HMODULE* handle, DWORD flags) {
  345. trace ("XLiveSecureLoadLibraryW\n");
  346. HMODULE module = LoadLibraryExW(path, NULL, flags);
  347. if(module)
  348. *handle = module;
  349. return GetLastError() | REASON_LEGACY_API;
  350. }
  351. // #5029
  352. extern "C" DWORD __stdcall XLiveSecureFreeLibrary(HMODULE module) {
  353. trace ("XLiveSecureFreeLibrary\n");
  354. FreeLibrary(module);
  355. return GetLastError() | REASON_LEGACY_API;
  356. }
  357. // #5030: XLivePreTranslateMessage
  358. extern "C" int __stdcall XLivePreTranslateMessage (DWORD) {
  359. return 0;
  360. }
  361. // #5031 XLiveSetDebugLevel
  362. extern "C" int __stdcall XLiveSetDebugLevel (DWORD xdlLevel, DWORD * pxdlOldLevel) {
  363. trace ("XLiveSetDebugLevel (%d)\n", xdlLevel);
  364. return 0;
  365. }
  366. // #5214: XShowPlayerReviewUI
  367. extern "C" int __stdcall XShowPlayerReviewUI (DWORD, DWORD, DWORD) {
  368. trace ("XShowPlayerReviewUI\n");
  369. return 0;
  370. }
  371. // #5215: XShowGuideUI
  372. extern "C" int __stdcall XShowGuideUI (DWORD) {
  373. trace ("XShowGuideUI\n");
  374. return 1;
  375. }
  376. // #5216: XShowKeyboardUI
  377. extern "C" int __stdcall XShowKeyboardUI (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  378. trace ("XShowKeyboardUI\n");
  379. return 0;
  380. }
  381. // #5250
  382. extern "C" DWORD __stdcall xlive_5250 (DWORD) {
  383. trace ("xlive_5250\n");
  384. return 0;
  385. }
  386. // #5251: XCloseHandle
  387. extern "C" int __stdcall XCloseHandle (HANDLE handle) {
  388. trace ("XCloseHandle\n");
  389. if(!handle || handle == (HANDLE)-1)
  390. {
  391. SetLastError(ERROR_INVALID_PARAMETER);
  392. return ERROR_INVALID_PARAMETER;
  393. }
  394. CloseHandle(handle);
  395. return 0;
  396. }
  397. // #5252: XShowGamerCardUI
  398. extern "C" int __stdcall XShowGamerCardUI (DWORD, DWORD, DWORD) {
  399. trace ("XShowGamerCardUI\n");
  400. return 0;
  401. }
  402. // #5254: XCancelOverlapped
  403. extern "C" int __stdcall XCancelOverlapped (DWORD* buffer) {
  404. trace ("XCancelOverlapped\n");
  405. if(buffer[0] == 0xDEADC0DE)
  406. {
  407. buffer[0] = 0;
  408. }
  409. return 0;
  410. }
  411. // #5256: XEnumerate
  412. extern "C" int __stdcall XEnumerate (HANDLE hEnum, void * pvBuffer, DWORD cbBuffer, DWORD * pcItemsReturned, void * pOverlapped) { // XEnumerate
  413. trace ("XEnumerate (buffer=> %p[%d])\n", pvBuffer, cbBuffer);
  414. // if (pvBuffer && cbBuffer)
  415. // memset (pvBuffer, 0, cbBuffer);
  416. if (pcItemsReturned)
  417. *pcItemsReturned = 0;
  418. return 0; // some error ?
  419. }
  420. // #5260: XShowSigninUI
  421. extern "C" int __stdcall XShowSigninUI (DWORD, DWORD) {
  422. trace ("XShowSigninUI\n");
  423. return 0;
  424. }
  425. // #5261: XUserGetXUID
  426. extern "C" int __stdcall XUserGetXUID (DWORD, DWORD * pXuid) {
  427. trace ("XUserGetXUID\n");
  428. pXuid[0] = 0xC0DEBEEF;
  429. pXuid[1] = 0x10001010;
  430. return 0; // ???
  431. }
  432. // #5262: XUserGetSigninState
  433. extern "C" int __stdcall XUserGetSigninState (DWORD dwUserIndex) {
  434. trace ("xlive_5262: XUserGetSigninState (%d)\n", dwUserIndex);
  435. if(dwUserIndex)
  436. return 0;
  437. return 2; // eXUserSigninState_SignedInLocally
  438. }
  439. // #5263: XUserGetName
  440. extern "C" int __stdcall XUserGetName (DWORD dwUserId, char * pBuffer, DWORD dwBufLen) {
  441. trace ("xlive_5263: XUserGetName (%d, .. , %d)\n", dwUserId, dwBufLen);
  442. if (dwBufLen < 8)
  443. return 1;
  444. memcpy (pBuffer, "Profile1", 8);
  445. return 0;
  446. }
  447. // #5264: XUserAreUsersFriends
  448. extern "C" int __stdcall XUserAreUsersFriends(DWORD dwUserIndex, DWORD * pXuids, DWORD dwXuidCount, DWORD * pResult, void * pOverlapped) {
  449. trace ("XUserAreUsersFriends\n");
  450. return ERROR_NOT_LOGGED_ON;
  451. }
  452. // #5265: XUserCheckPrivilege
  453. extern "C" int __stdcall XUserCheckPrivilege (DWORD user, DWORD priv, PBOOL b) {
  454. trace ("XUserCheckPrivilege (%d, %d, ..)\n", user, priv);
  455. *b = false;
  456. return ERROR_NOT_LOGGED_ON;
  457. }
  458. // #5266
  459. extern "C" DWORD __stdcall xlive_5266(DWORD p1, DWORD* p2, DWORD* p3, DWORD p4, DWORD p5, DWORD p6, DWORD p7, DWORD* p8, PXOVERLAPPED p9) {
  460. trace ("xlive_5266(%x, %p, %p, %x, %p, %x, %x, %p, %p)\n", p1, p2, p3, p4, p5, p6, p7, p8, p9);
  461. *p8 = 0;
  462. p9->InternalLow = 0xC0DEBEEF;
  463. p9->InternalHigh = 0;
  464. return 0;
  465. }
  466. struct XUSER_SIGNIN_INFO {
  467. DWORD xuidL; // 0
  468. DWORD xuidH; // 4
  469. DWORD dwInfoFlags; // 8
  470. DWORD UserSigninState; // 12
  471. DWORD dwGuestNumber; // 16
  472. DWORD dwSponsorUserIndex; // 20
  473. CHAR szUserName[16]; // 24
  474. };
  475. // #5267: XUserGetSigninInfo
  476. extern "C" int __stdcall XUserGetSigninInfo (DWORD dwUser, DWORD dwFlags, XUSER_SIGNIN_INFO * pInfo) {
  477. //trace ("XUserGetSigninInfo (%d, %d, ...)\n", dwUser, dwFlags);
  478. memset(pInfo, 0, sizeof(XUSER_SIGNIN_INFO));
  479. if(dwFlags & 2)
  480. {
  481. pInfo->UserSigninState = 2;
  482. }
  483. else
  484. {
  485. pInfo->UserSigninState = 1;
  486. }
  487. pInfo->xuidL = 0x10001010;
  488. pInfo->xuidH = 0xC0DEBEEF;
  489. pInfo->dwInfoFlags = 1;
  490. pInfo->dwGuestNumber = 0;
  491. pInfo->dwSponsorUserIndex = 254;
  492. strcpy(pInfo->szUserName, "Profile1");
  493. return 0;
  494. }
  495. // #5270: XNotifyCreateListener
  496. extern "C" HANDLE __stdcall XNotifyCreateListener (DWORD l, DWORD h) {
  497. trace ("xlive_5270: XNotifyCreateListener (0x%08x%08x)\n", h, l);
  498. return (HANDLE)1; // any non-zero value. (zero treated as fatal error)
  499. }
  500. // #5273: XUserReadGamerpictureByKey
  501. extern "C" int __stdcall XUserReadGamerpictureByKey (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  502. trace ("XUserReadGamerpictureByKey\n");
  503. return 0;
  504. }
  505. // #5274: unknown friend api
  506. extern "C" DWORD __stdcall xlive_5274(DWORD, DWORD, DWORD, DWORD) {
  507. trace ("xlive_5274\n");
  508. return 0;
  509. }
  510. // #5275: XShowFriendsUI
  511. extern "C" int __stdcall XShowFriendsUI (DWORD) {
  512. trace ("XShowFriendsUI\n");
  513. return 0;
  514. }
  515. // #5276: XUserSetProperty
  516. extern "C" int __stdcall XUserSetProperty (DWORD, DWORD, DWORD, DWORD) {
  517. trace ("XUserSetProperty\n");
  518. return 0;
  519. }
  520. // #5277: XUserSetContext
  521. extern "C" int __stdcall XUserSetContext (DWORD, DWORD, DWORD) {
  522. trace ("XUserSetContext\n");
  523. return 0;
  524. }
  525. // #5278: XUserWriteAchievements
  526. extern "C" DWORD __stdcall XUserWriteAchievements (DWORD, DWORD, DWORD) {
  527. trace ("XUserWriteAchievements\n");
  528. return 0;
  529. }
  530. // #5280: XUserCreateAchievementEnumerator
  531. extern "C" DWORD __stdcall XUserCreateAchievementEnumerator (DWORD dwTitleId, DWORD dwUserIndex, DWORD xuidL, DWORD xuidHi, DWORD dwDetailFlags, DWORD dwStartingIndex, DWORD cItem, DWORD * pcbBuffer, HANDLE * phEnum) {
  532. trace ("XUserCreateAchievementEnumerator (dwStartingIndex=>%d, cItem=>%d \n", dwStartingIndex, cItem);
  533. if (pcbBuffer)
  534. *pcbBuffer = 0;
  535. if (phEnum)
  536. *phEnum = INVALID_HANDLE_VALUE;
  537. return 1; // return error (otherwise, 0-size buffer will be allocated)
  538. }
  539. // #5281: XUserReadStats
  540. extern "C" DWORD __stdcall XUserReadStats (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD * pcbResults, DWORD * pResults, void *) {
  541. trace ("XUserReadStats\n");
  542. if (pcbResults)
  543. *pcbResults = 4;
  544. if (pResults)
  545. *pResults = 0;
  546. return 0;
  547. }
  548. // #5284: XUserCreateStatsEnumeratorByRank
  549. extern "C" DWORD __stdcall XUserCreateStatsEnumeratorByRank (DWORD dwTitleId, DWORD dwRankStart, DWORD dwNumRows, DWORD dwNuStatSpec, void * pSpecs, DWORD * pcbBuffer, PHANDLE phEnum) {
  550. trace ("XUserCreateStatsEnumeratorByRank\n");
  551. if (pcbBuffer)
  552. *pcbBuffer = 0;
  553. *phEnum = INVALID_HANDLE_VALUE;
  554. return 1;
  555. }
  556. // #5286: XUserCreateStatsEnumeratorByXuid
  557. extern "C" DWORD __stdcall XUserCreateStatsEnumeratorByXuid (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD * pcbBuffer, PHANDLE phEnum) {
  558. trace ("XUserCreateStatsEnumeratorByXuid\n");
  559. if (pcbBuffer)
  560. pcbBuffer = 0;
  561. *phEnum = INVALID_HANDLE_VALUE;
  562. return 1;
  563. }
  564. // #5292: XUserSetContextEx
  565. extern "C" int __stdcall XUserSetContextEx (DWORD dwUserIndex, DWORD dwContextId, DWORD dwContextValue, void * pOverlapped) {
  566. trace ("XUserSetContextEx\n");
  567. return 0;
  568. }
  569. // #5293: XUserSetPropertyEx
  570. extern "C" int __stdcall XUserSetPropertyEx (DWORD dwUserIndex, DWORD dwPropertyId, DWORD cbValue, void * pvValue, void * pOverlapped) {
  571. trace ("XUserSetPropertyEx (%d, 0x%x, ...)\n", dwUserIndex, dwPropertyId);
  572. return 0;
  573. }
  574. // #5297: XLiveInitializeEx
  575. extern "C" int __stdcall XLiveInitializeEx (void * pXii, DWORD dwVersion) {
  576. trace ("XLiveInitializeEx\n");
  577. return 0;
  578. }
  579. // #5300: XSessionCreate
  580. extern "C" DWORD __stdcall XSessionCreate (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  581. trace ("XSessionCreate\n");
  582. return -1;
  583. }
  584. // #5303: XStringVerify
  585. extern "C" DWORD __stdcall XStringVerify (DWORD, DWORD, DWORD, DWORD, DWORD, WORD * pResult, DWORD) { // XStringVerify
  586. trace ("XStringVerify\n");
  587. *pResult = 0;
  588. return 0;
  589. }
  590. // #5305: XStorageUploadFromMemory
  591. extern "C" DWORD __stdcall XStorageUploadFromMemory (DWORD, DWORD, DWORD, DWORD, DWORD) {
  592. trace ("XStorageUploadFromMemory\n");
  593. return 0;
  594. }
  595. // #5306: XStorageEnumerate
  596. extern "C" int __stdcall XStorageEnumerate (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) { // XStorageEnumerate
  597. trace ("XStorageEnumerate\n");
  598. return 0;
  599. }
  600. extern "C" DWORD __stdcall xlive_5309(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  601. trace ("xlive_5309\n");
  602. return 0;
  603. }
  604. // #5310: XOnlineStartup
  605. extern "C" int __stdcall XOnlineStartup () {
  606. trace ("XOnlineStartup\n");
  607. return 0;
  608. }
  609. // #5311: XOnlineCleanup
  610. extern "C" int __stdcall XOnlineCleanup () {
  611. trace ("XOnlineCleanup\n");
  612. return 0;
  613. }
  614. // #5312: XFriendsCreateEnumerator
  615. extern "C" DWORD __stdcall XFriendsCreateEnumerator (DWORD, DWORD, DWORD, DWORD, HANDLE * phEnum) {
  616. trace ("XFriendsCreateEnumerator\n");
  617. *phEnum = INVALID_HANDLE_VALUE;
  618. return 0;
  619. }
  620. // #5314: XUserMuteListQuery
  621. extern "C" int __stdcall XUserMuteListQuery (DWORD, DWORD, DWORD, DWORD) {
  622. trace ("XUserMuteListQuery\n");
  623. return 0;
  624. }
  625. // #5315: XInviteGetAcceptedInfo
  626. extern "C" int __stdcall XInviteGetAcceptedInfo (DWORD, DWORD) {
  627. trace ("XInviteGetAcceptedInfo\n");
  628. return 1;
  629. }
  630. // #5316: XInviteSend
  631. extern "C" int __stdcall XInviteSend (DWORD, DWORD, DWORD, DWORD, DWORD) {
  632. trace ("XInviteSend\n");
  633. return 0;
  634. }
  635. // #5317: XSessionWriteStats
  636. extern "C" DWORD __stdcall XSessionWriteStats (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  637. trace ("XSessionWriteStats\n");
  638. return 0;
  639. }
  640. // #5318
  641. extern "C" int __stdcall XSessionStart (DWORD, DWORD, DWORD) {
  642. trace ("XSessionStart\n");
  643. return 0;
  644. }
  645. // #5319: XSessionSearchEx
  646. extern "C" DWORD __stdcall XSessionSearchEx (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  647. trace ("XSessionSearchEx\n");
  648. return 0;
  649. }
  650. // #5320
  651. extern "C" DWORD __stdcall xlive_5320 (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  652. trace ("xlive_5320\n");
  653. return 0;
  654. }
  655. // #5321
  656. extern "C" DWORD __stdcall xlive_5321 (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD* p9, DWORD) {
  657. trace ("xlive_5321\n");
  658. if(p9)
  659. *p9 = 0;
  660. return 0;
  661. }
  662. // #5322: XSessionModify
  663. extern "C" DWORD __stdcall XSessionModify (DWORD, DWORD, DWORD, DWORD, DWORD) {
  664. trace ("XSessionModify\n");
  665. return 0;
  666. }
  667. // #5323: XSessionMigrateHost
  668. extern "C" DWORD __stdcall XSessionMigrateHost (DWORD, DWORD, DWORD, DWORD) {
  669. trace ("XSessionMigrateHost\n");
  670. return 0;
  671. }
  672. // #5324: XOnlineGetNatType
  673. extern "C" int __stdcall XOnlineGetNatType () {
  674. trace ("XOnlineGetNatType\n");
  675. return 0;
  676. }
  677. // #5325: XSessionLeaveLocal
  678. extern "C" DWORD __stdcall XSessionLeaveLocal (DWORD, DWORD, DWORD, DWORD) {
  679. trace ("XSessionLeaveLocal\n");
  680. return 0;
  681. }
  682. // #5326: XSessionJoinRemote
  683. extern "C" DWORD __stdcall XSessionJoinRemote (DWORD, DWORD, DWORD, DWORD, DWORD) {
  684. trace ("XSessionJoinRemote\n");
  685. return 0;
  686. }
  687. // #5327: XSessionJoinLocal
  688. extern "C" DWORD __stdcall XSessionJoinLocal (DWORD, DWORD, DWORD, DWORD, DWORD) {
  689. trace ("XSessionJoinLocal\n");
  690. return 0;
  691. }
  692. // #5328: XSessionGetDetails
  693. extern "C" DWORD __stdcall XSessionGetDetails (DWORD, DWORD, DWORD, DWORD) {
  694. trace ("XSessionGetDetails\n");
  695. return 0;
  696. }
  697. // #5329: XSessionFlushStats
  698. extern "C" int __stdcall XSessionFlushStats (DWORD, DWORD) {
  699. trace ("XSessionFlushStats\n");
  700. return 0;
  701. }
  702. // #5330: XSessionDelete
  703. extern "C" DWORD __stdcall XSessionDelete (DWORD, DWORD) {
  704. trace ("XSessionDelete\n");
  705. return 0;
  706. }
  707. struct XUSER_READ_PROFILE_SETTINGS {
  708. DWORD dwLength;
  709. BYTE * pSettings;
  710. };
  711. // #5331: XUserReadProfileSettings
  712. extern "C" DWORD __stdcall XUserReadProfileSettings (DWORD dwTitleId, DWORD dwUserIndex, DWORD dwNumSettingIds,
  713. DWORD * pdwSettingIds, DWORD * pcbResults, XUSER_READ_PROFILE_SETTINGS * pResults, DWORD pOverlapped) {
  714. trace ("XUserReadProfileSettings (%d, %d, %d, ..., %d, ...)\n", dwTitleId, dwUserIndex, dwNumSettingIds, *pcbResults);
  715. if (*pcbResults < 1036) {
  716. *pcbResults = 1036; // TODO: make correct calculation by IDs.
  717. return ERROR_INSUFFICIENT_BUFFER;
  718. }
  719. memset (pResults, 0, *pcbResults);
  720. pResults->dwLength = *pcbResults-sizeof (XUSER_READ_PROFILE_SETTINGS);
  721. pResults->pSettings = (BYTE *)pResults+sizeof (XUSER_READ_PROFILE_SETTINGS);
  722. return 0;
  723. }
  724. // #5332: XSessionEnd
  725. extern "C" int __stdcall XSessionEnd (DWORD, DWORD) {
  726. trace ("XSessionEnd\n");
  727. return 0;
  728. }
  729. // #5333: XSessionArbitrationRegister
  730. extern "C" DWORD __stdcall XSessionArbitrationRegister (DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD) {
  731. trace ("XSessionArbitrationRegister\n");
  732. return 0;
  733. }
  734. // #5335: XTitleServerCreateEnumerator
  735. extern "C" DWORD __stdcall XTitleServerCreateEnumerator (LPCSTR pszServerInfo, DWORD cItem, DWORD * pcbBuffer, PHANDLE phEnum) {
  736. trace ("XTitleServerCreateEnumerator (cItem=> %d)\n", cItem);
  737. if(pcbBuffer)
  738. *pcbBuffer = 0;
  739. *phEnum = INVALID_HANDLE_VALUE;
  740. return 1;
  741. }
  742. // #5336: XSessionLeaveRemote
  743. extern "C" DWORD __stdcall XSessionLeaveRemote (DWORD, DWORD, DWORD, DWORD) {
  744. trace ("XSessionLeaveRemote\n");
  745. return 0;
  746. }
  747. // #5337: XUserWriteProfileSettings
  748. extern "C" DWORD __stdcall XUserWriteProfileSettings (DWORD, DWORD, DWORD, DWORD) {
  749. trace ("XUserWriteProfileSettings\n");
  750. return 0;
  751. }
  752. // #5339: XUserReadProfileSettingsByXuid
  753. extern "C" DWORD __stdcall XUserReadProfileSettingsByXuid (DWORD, DWORD, DWORD, DWORD,DWORD, DWORD,DWORD, DWORD,DWORD) {
  754. trace ("XUserReadProfileSettingsByXuid\n");
  755. return 0;
  756. }
  757. // #5342
  758. extern "C" DWORD __stdcall xlive_5342(DWORD, DWORD, DWORD, DWORD) {
  759. trace ("xlive_5342\n");
  760. return 0;
  761. }
  762. // #5343: XLiveCalculateSkill
  763. extern "C" DWORD __stdcall XLiveCalculateSkill (DWORD, DWORD, DWORD, DWORD, DWORD) {
  764. trace ("XLiveCalculateSkill\n");
  765. return 0;
  766. }
  767. // #5344: XStorageBuildServerPath
  768. extern "C" DWORD __stdcall XStorageBuildServerPath (DWORD dwUserIndex, DWORD StorageFacility,
  769. void * pvStorageFacilityInfo, DWORD dwStorageFacilityInfoSize,
  770. void * pwszItemName, void * pwszServerPath, DWORD * pdwServerPathLength) {
  771. trace ("XStorageBuildServerPath\n");
  772. return 0;
  773. }
  774. // #5345: XStorageDownloadToMemory
  775. extern "C" DWORD __stdcall XStorageDownloadToMemory (DWORD dwUserIndex, DWORD, DWORD, DWORD, DWORD, DWORD, void * ) {
  776. trace ("XStorageDownloadToMemory\n");
  777. return 0;
  778. }
  779. // #5347 XLiveSecureLoadLibraryExW
  780. extern "C" DWORD __stdcall XLiveSecureLoadLibraryExW(DWORD a, DWORD, LPCWSTR lpModuleName, DWORD flags, HMODULE* handle) {
  781. trace ("XLiveSecureLoadLibraryExW\n");
  782. if(a)
  783. return E_INVALIDARG;
  784. return XLiveSecureLoadLibraryW(lpModuleName, handle, flags);
  785. }
  786. // #5348 XLiveSecureCreateFileW
  787. extern "C" DWORD __stdcall XLiveSecureCreateFileW (DWORD something, DWORD, LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  788. DWORD, DWORD dwFlagsAndAttributes, HANDLE* fileHandle)
  789. {
  790. trace ("XLiveSecureCreateFileW %S\n", lpFileName);
  791. if ( something )
  792. return E_INVALIDARG;
  793. *fileHandle = CreateFileW(
  794. lpFileName,
  795. dwDesiredAccess,
  796. dwShareMode,
  797. lpSecurityAttributes,
  798. 3u,
  799. dwFlagsAndAttributes,
  800. 0);
  801. return 0;
  802. }
  803. // #5349: XLiveProtectedVerifyFile
  804. extern "C" DWORD __stdcall XLiveProtectedVerifyFile (HANDLE hContentAccess, VOID * pvReserved, PCWSTR pszFilePath) {
  805. trace ("XLiveProtectedVerifyFile\n");
  806. return 0;
  807. }
  808. // #5350: XLiveContentCreateAccessHandle
  809. extern "C" DWORD __stdcall XLiveContentCreateAccessHandle (DWORD dwTitleId, void * pContentInfo,
  810. DWORD dwLicenseInfoVersion, void * xebBuffer, DWORD dwOffset, HANDLE * phAccess, void * pOverlapped) {
  811. trace ("XLiveContentCreateAccessHandle\n");
  812. if (phAccess)
  813. *phAccess = INVALID_HANDLE_VALUE;
  814. return E_OUTOFMEMORY; // TODO: fix it
  815. }
  816. // #5352: XLiveContentUninstall
  817. extern "C" DWORD __stdcall XLiveContentUninstall (void * pContentInfo, void * pxuidFor, void * pInstallCallbackParams) {
  818. trace ("XLiveContentUninstall\n");
  819. return 0;
  820. }
  821. // #5354
  822. extern "C" DWORD __stdcall xlive_5354(DWORD, DWORD) {
  823. trace ("xlive_5354\n");
  824. return 0;
  825. }
  826. // #5355: XLiveContentGetPath
  827. extern "C" DWORD __stdcall XLiveContentGetPath (DWORD dwUserIndex, void * pContentInfo, wchar_t * pszPath, DWORD * pcchPath) {
  828. trace ("XLiveContentGetPath\n");
  829. if (pcchPath)
  830. *pcchPath = 0;
  831. if (pszPath)
  832. *pszPath = 0;
  833. return 0;
  834. }
  835. // #5356
  836. extern "C" DWORD __stdcall xlive_5356 (DWORD, DWORD, DWORD, DWORD) {
  837. trace ("xlive_5356\n");
  838. return 0;
  839. }
  840. // #5360: XLiveContentCreateEnumerator
  841. extern "C" DWORD __stdcall XLiveContentCreateEnumerator (DWORD, void *, DWORD *pchBuffer, HANDLE * phContent) {
  842. trace ("XLiveContentCreateEnumerator\n");
  843. if (phContent)
  844. *phContent = 0;
  845. //*phContent = INVALID_HANDLE_VALUE;
  846. if (pchBuffer)
  847. *pchBuffer = 0;
  848. return 1;
  849. }
  850. // #5361: XLiveContentRetrieveOffersByDate
  851. extern "C" DWORD __stdcall XLiveContentRetrieveOffersByDate (DWORD dwUserIndex, DWORD dwOffserInfoVersion,
  852. SYSTEMTIME * pstStartDate, void * pOffserInfoArray, DWORD * pcOfferInfo, void * pOverlapped) {
  853. trace ("XLiveContentRetrieveOffersByDate\n");
  854. if (pcOfferInfo)
  855. *pcOfferInfo = 0;
  856. return 0;
  857. }
  858. // #5365: XShowMarketplaceUI
  859. extern "C" DWORD __stdcall XShowMarketplaceUI (DWORD dwUserIndex, DWORD dwEntryPoint, ULONGLONG dwOfferId, DWORD dwContentCategories) {
  860. return 1;
  861. }
  862. // === replacements ===
  863. struct FakeProtectedBuffer {
  864. DWORD dwMagick;
  865. DWORD dwSize;
  866. DWORD __fill[2]; // To match buffer size in Rick's wrapper
  867. BYTE bData[4];
  868. };
  869. // #5016: XLivePBufferAllocate
  870. extern "C" DWORD __stdcall XLivePBufferAllocate (int size, FakeProtectedBuffer ** pBuffer) {
  871. // trace ("xlive_5016: XLivePBufferAllocate (%d)\n", size);
  872. *pBuffer = (FakeProtectedBuffer *)malloc (size+16);
  873. if (!*pBuffer) {
  874. trace ("ERROR: XLivePBufferAllocate unable to allocate %d bytes\n", size);
  875. return E_OUTOFMEMORY;
  876. }
  877. (*pBuffer)->dwMagick = 0xDEADDEAD; // some arbitrary number
  878. (*pBuffer)->dwSize = size;
  879. return 0;
  880. }
  881. // #5017: XLivePBufferFree
  882. extern "C" DWORD __stdcall XLivePBufferFree (FakeProtectedBuffer * pBuffer) {
  883. // trace ("xlive_5017: XLivePBufferFree\n");
  884. if (pBuffer && pBuffer->dwMagick == 0xDEADDEAD)
  885. free (pBuffer);
  886. return 0;
  887. }
  888. // #5295: XLivePBufferSetByteArray
  889. extern "C" DWORD __stdcall XLivePBufferSetByteArray (FakeProtectedBuffer * pBuffer, DWORD offset, BYTE * source, DWORD size) {
  890. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || !source || offset < 0 || offset+size > pBuffer->dwSize)
  891. return 0;
  892. memcpy (pBuffer->bData+offset, source, size);
  893. return 0;
  894. }
  895. // #5294: XLivePBufferGetByteArray
  896. extern "C" DWORD __stdcall XLivePBufferGetByteArray (FakeProtectedBuffer * pBuffer, DWORD offset, BYTE * destination, DWORD size) {
  897. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || !destination || offset < 0 || offset+size > pBuffer->dwSize)
  898. return 0;
  899. memcpy (destination, pBuffer->bData+offset, size);
  900. return 0;
  901. }
  902. // #5019: XLivePBufferSetByte
  903. extern "C" DWORD __stdcall XLivePBufferSetByte (FakeProtectedBuffer * pBuffer, DWORD offset, BYTE value) {
  904. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || offset < 0 || offset > pBuffer->dwSize)
  905. return 0;
  906. pBuffer->bData[offset] = value;
  907. return 0;
  908. }
  909. // #5018: XLivePBufferGetByte
  910. extern "C" DWORD __stdcall XLivePBufferGetByte (FakeProtectedBuffer * pBuffer, DWORD offset, BYTE * value) {
  911. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || !value || offset < 0 || offset > pBuffer->dwSize)
  912. return 0;
  913. *value = pBuffer->bData[offset];
  914. return 0;
  915. }
  916. // #5020: XLivePBufferGetDWORD
  917. extern "C" DWORD __stdcall XLivePBufferGetDWORD (FakeProtectedBuffer * pBuffer, DWORD dwOffset, DWORD * pdwValue) {
  918. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || dwOffset < 0 || dwOffset > pBuffer->dwSize-4 || !pdwValue)
  919. return 0;
  920. *pdwValue = *(DWORD *)(pBuffer->bData+dwOffset);
  921. return 0;
  922. }
  923. // #5021: XLivePBufferSetDWORD
  924. extern "C" DWORD __stdcall XLivePBufferSetDWORD (FakeProtectedBuffer * pBuffer, DWORD dwOffset, DWORD dwValue ) {
  925. if (!pBuffer || pBuffer->dwMagick != 0xDEADDEAD || dwOffset < 0 || dwOffset > pBuffer->dwSize-4)
  926. return 0;
  927. *(DWORD *)(pBuffer->bData+dwOffset) = dwValue;
  928. return 0;
  929. }
  930. // #5026: XLiveSetSponsorToken
  931. extern "C" DWORD __stdcall XLiveSetSponsorToken (LPCWSTR pwszToken, DWORD dwTitleId) {
  932. trace ("XLiveSetSponsorToken (, 0x%08x)\n", dwTitleId);
  933. return S_OK;
  934. }
  935. // #5036: XLiveCreateProtectedDataContext
  936. extern "C" DWORD __stdcall XLiveCreateProtectedDataContext (DWORD * dwType, PHANDLE pHandle) {
  937. trace ("XLiveCreateProtectedDataContext\n");
  938. if (pHandle)
  939. *pHandle = (HANDLE)1;
  940. return 0;
  941. }
  942. // #5037: XLiveQueryProtectedDataInformation
  943. extern "C" DWORD __stdcall XLiveQueryProtectedDataInformation (HANDLE h, DWORD * p) {
  944. trace ("XLiveQueryProtectedDataInformation\n");
  945. return 0;
  946. }
  947. // #5038: XLiveCloseProtectedDataContext
  948. extern "C" DWORD __stdcall XLiveCloseProtectedDataContext (HANDLE h) {
  949. trace ("XLiveCloseProtectedDataContext\n");
  950. return 0;
  951. }
  952. // #5035: XLiveUnprotectData
  953. extern "C" DWORD __stdcall XLiveUnprotectData (BYTE * pInBuffer, DWORD dwInDataSize, BYTE * pOutBuffer, DWORD * pDataSize, HANDLE * ph) {
  954. trace ("XLiveUnprotectData (..., %d, ..., %d, %d)\n", dwInDataSize, *pDataSize, *(DWORD*)ph);
  955. if (!pDataSize || !ph) // invalid parameter
  956. return E_FAIL;
  957. *ph = (HANDLE)1;
  958. if (!pOutBuffer || *pDataSize < dwInDataSize) {
  959. *pDataSize = dwInDataSize;
  960. return ERROR_INSUFFICIENT_BUFFER;
  961. }
  962. *pDataSize = dwInDataSize;
  963. memcpy (pOutBuffer, pInBuffer, dwInDataSize);
  964. return 0;
  965. }
  966. // #5034: XLiveProtectData
  967. extern "C" DWORD __stdcall XLiveProtectData (BYTE * pInBuffer, DWORD dwInDataSize, BYTE * pOutBuffer, DWORD * pDataSize, HANDLE h) {
  968. trace ("XLiveProtectData (..., %d, ..., %d, %d)\n", dwInDataSize, *pDataSize, (DWORD)h);
  969. *pDataSize = dwInDataSize;
  970. if (pOutBuffer)
  971. {
  972. memcpy (pOutBuffer, pInBuffer, dwInDataSize);
  973. }
  974. else
  975. {
  976. return 0x8007007A;
  977. }
  978. return 0;
  979. }
  980. // #5367
  981. extern "C" DWORD __stdcall xlive_5367 (HANDLE, DWORD, DWORD, BYTE *, DWORD) {
  982. trace ("xlive_5367\n");
  983. return 1;
  984. }
  985. // #5372
  986. extern "C" DWORD __stdcall xlive_5372 (HANDLE, DWORD, DWORD, DWORD, BYTE *, HANDLE) {
  987. trace ("xlive_5372\n");
  988. return 1;
  989. }
  990. // === end of xlive functions ===
  991. static char * pszPath = "";
  992. // change savefile path to "%USERPROFILE%\Documents\Rockstar Games\GTA IV\savegames\"
  993. void getSavefilePath (int __unused, char * pBuffer, char * pszSaveName) {
  994. strcpy_s (pBuffer, 256, pszPath);
  995. strcat_s (pBuffer, 256, "savegames");
  996. // check path and create directory if necessary
  997. DWORD attrs = GetFileAttributes (pBuffer);
  998. if (attrs == INVALID_FILE_ATTRIBUTES)
  999. CreateDirectory (pBuffer, NULL);
  1000. else if (!(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
  1001. trace ("ERROR: unable to create directory '%s', file '%s' already exists\n", pBuffer);
  1002. strcpy_s (pBuffer, 256, pszSaveName);
  1003. return;
  1004. }
  1005. if (pszSaveName) {
  1006. strcat_s (pBuffer, 256, "\\");
  1007. strcat_s (pBuffer, 256, pszSaveName);
  1008. }
  1009. trace ("[getSavefilePath]: '%s'\n", pBuffer);
  1010. }
  1011. void patchCode () {
  1012. // get load address of the exe
  1013. dwLoadOffset = (DWORD)GetModuleHandle (NULL);
  1014. trace ("GetModuleHandle returns %08x\n", dwLoadOffset);
  1015. // Unprotect image - make .text and .rdata section writeable
  1016. BYTE * pImageBase = reinterpret_cast<BYTE *>(dwLoadOffset);
  1017. PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER> (dwLoadOffset);
  1018. PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS> (pImageBase+pDosHeader->e_lfanew);
  1019. PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeader);
  1020. // trace ("[EXE] NtHeader contains %d sections\n", pNtHeaders->FileHeader.NumberOfSections);
  1021. for (int iSection = 0; iSection < pNtHeader->FileHeader.NumberOfSections; ++iSection, ++pSection) {
  1022. char * pszSectionName = reinterpret_cast<char *>(pSection->Name);
  1023. if (!strcmp (pszSectionName, ".text") || !strcmp (pszSectionName, ".rdata")) {
  1024. DWORD dwPhysSize = (pSection->Misc.VirtualSize + 4095) & ~4095;
  1025. trace ("[EXE] unprotecting section '%s': addr = 0x%08x, size = 0x%08x\n", pSection->Name, pSection->VirtualAddress, dwPhysSize);
  1026. DWORD oldProtect;
  1027. DWORD newProtect = (pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  1028. if (!VirtualProtect (reinterpret_cast <VOID *>(dwLoadOffset+pSection->VirtualAddress), dwPhysSize, newProtect, &oldProtect)) {
  1029. trace ("[EXE] Virtual protect error\n");
  1030. ExitProcess (0);
  1031. }
  1032. }
  1033. }
  1034. dwLoadOffset -= 0x400000;
  1035. // ExitProcess (0);
  1036. // version check
  1037. DWORD signature = *(DWORD *)(0x608C34+dwLoadOffset);
  1038. switch (signature)
  1039. {
  1040. default:
  1041. trace ("Unknown game version, skipping patches (signature = 0x%08x)\n", signature);
  1042. break;
  1043. }
  1044. }
  1045. // Plugin Loader
  1046. void loadPlugins (char * pszMask) {
  1047. if (!pszMask)
  1048. return;
  1049. char * pszType = strrchr (pszMask, '.');
  1050. DWORD typeMask = pszType ? *(DWORD *)pszType : 0x6c6c642e; // '.dll'
  1051. WIN32_FIND_DATA fd;
  1052. char pathName[MAX_PATH]; // module name buffer
  1053. char * p = strrchr (pszMask, '\\');
  1054. char * namePtr = pathName;
  1055. if (p) {
  1056. strcpy_s (pathName, MAX_PATH, pszMask);
  1057. pathName[p-pszMask+1] = '\0';
  1058. namePtr = pathName + (p-pszMask+1);
  1059. }
  1060. HANDLE asiFile = FindFirstFile (pszMask, &fd);
  1061. if (asiFile == INVALID_HANDLE_VALUE)
  1062. return;
  1063. do {
  1064. if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  1065. int pos = 0;
  1066. while (fd.cFileName[pos])
  1067. pos++;
  1068. DWORD type = *(DWORD *)(fd.cFileName+pos-4);
  1069. type |= 0x20202020; // convert to lowercase
  1070. if (type == typeMask) {
  1071. strcpy (namePtr, fd.cFileName);
  1072. if (!LoadLibrary (pathName))
  1073. trace ("Error loading library %d\n", GetLastError ());
  1074. trace ("plugin loader: loaded '%s'\n", pathName);
  1075. }
  1076. }
  1077. } while (FindNextFile (asiFile, &fd));
  1078. FindClose (asiFile);
  1079. }
  1080. //=============================================================================
  1081. // Entry Point
  1082. BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
  1083. switch (ul_reason_for_call) {
  1084. case DLL_PROCESS_ATTACH:
  1085. #ifndef NO_TRACE
  1086. logfile = fopen ("xlive_trace.log", "at"); // TODO: move log to the User\Documents or something
  1087. if (logfile)
  1088. InitializeCriticalSection (&d_lock);
  1089. trace ("Log started (xliveless 1.0b1)\n");
  1090. #endif
  1091. patchCode ();
  1092. loadPlugins ("*.asi");
  1093. loadPlugins ("plugins\\*.asi");
  1094. loadPlugins ("plugins\\*.dll");
  1095. break;
  1096. case DLL_THREAD_ATTACH:
  1097. case DLL_THREAD_DETACH:
  1098. break;
  1099. case DLL_PROCESS_DETACH:
  1100. #ifndef NO_TRACE
  1101. if (logfile) {
  1102. EnterCriticalSection (&d_lock);
  1103. fflush (logfile);
  1104. fclose (logfile);
  1105. logfile = NULL;
  1106. LeaveCriticalSection (&d_lock);
  1107. DeleteCriticalSection (&d_lock);
  1108. }
  1109. #endif
  1110. break;
  1111. }
  1112. return TRUE;
  1113. }