1 /* 2 * Implementation of mscoree.dll 3 * Microsoft Component Object Runtime Execution Engine 4 * 5 * Copyright 2006 Paul Chitescu 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "mscoree_private.h" 23 24 #include <rpcproxy.h> 25 26 static HINSTANCE MSCOREE_hInstance; 27 28 typedef HRESULT (*fnCreateInstance)(REFIID riid, LPVOID *ppObj); 29 30 char *WtoA(LPCWSTR wstr) 31 { 32 int length; 33 char *result; 34 35 length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); 36 37 result = HeapAlloc(GetProcessHeap(), 0, length); 38 39 if (result) 40 WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, length, NULL, NULL); 41 42 return result; 43 } 44 45 static BOOL get_install_root(LPWSTR install_dir) 46 { 47 const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0}; 48 const WCHAR install_root[] = {'I','n','s','t','a','l','l','R','o','o','t',0}; 49 50 DWORD len; 51 HKEY key; 52 53 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, dotnet_key, 0, KEY_READ, &key)) 54 return FALSE; 55 56 len = MAX_PATH * sizeof(WCHAR); 57 if (RegQueryValueExW(key, install_root, 0, NULL, (LPBYTE)install_dir, &len)) 58 { 59 RegCloseKey(key); 60 return FALSE; 61 } 62 RegCloseKey(key); 63 64 return TRUE; 65 } 66 67 typedef struct mscorecf 68 { 69 IClassFactory IClassFactory_iface; 70 LONG ref; 71 72 fnCreateInstance pfnCreateInstance; 73 74 CLSID clsid; 75 } mscorecf; 76 77 static inline mscorecf *impl_from_IClassFactory( IClassFactory *iface ) 78 { 79 return CONTAINING_RECORD(iface, mscorecf, IClassFactory_iface); 80 } 81 82 static HRESULT WINAPI mscorecf_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *ppobj ) 83 { 84 TRACE("%s %p\n", debugstr_guid(riid), ppobj); 85 86 if (IsEqualGUID(riid, &IID_IUnknown) || 87 IsEqualGUID(riid, &IID_IClassFactory)) 88 { 89 IClassFactory_AddRef( iface ); 90 *ppobj = iface; 91 return S_OK; 92 } 93 94 ERR("interface %s not implemented\n", debugstr_guid(riid)); 95 return E_NOINTERFACE; 96 } 97 98 static ULONG WINAPI mscorecf_AddRef(IClassFactory *iface ) 99 { 100 mscorecf *This = impl_from_IClassFactory(iface); 101 ULONG ref = InterlockedIncrement(&This->ref); 102 103 TRACE("%p ref=%u\n", This, ref); 104 105 return ref; 106 } 107 108 static ULONG WINAPI mscorecf_Release(IClassFactory *iface ) 109 { 110 mscorecf *This = impl_from_IClassFactory(iface); 111 ULONG ref = InterlockedDecrement(&This->ref); 112 113 TRACE("%p ref=%u\n", This, ref); 114 115 if (ref == 0) 116 { 117 HeapFree(GetProcessHeap(), 0, This); 118 } 119 120 return ref; 121 } 122 123 static HRESULT WINAPI mscorecf_CreateInstance(IClassFactory *iface,LPUNKNOWN pOuter, 124 REFIID riid, LPVOID *ppobj ) 125 { 126 mscorecf *This = impl_from_IClassFactory( iface ); 127 HRESULT hr; 128 IUnknown *punk; 129 130 TRACE("%p %s %p\n", pOuter, debugstr_guid(riid), ppobj ); 131 132 *ppobj = NULL; 133 134 if (pOuter) 135 return CLASS_E_NOAGGREGATION; 136 137 hr = This->pfnCreateInstance( &This->clsid, (LPVOID*) &punk ); 138 if (SUCCEEDED(hr)) 139 { 140 hr = IUnknown_QueryInterface( punk, riid, ppobj ); 141 142 IUnknown_Release( punk ); 143 } 144 else 145 { 146 WARN("Cannot create an instance object. 0x%08x\n", hr); 147 } 148 return hr; 149 } 150 151 static HRESULT WINAPI mscorecf_LockServer(IClassFactory *iface, BOOL dolock) 152 { 153 FIXME("(%p)->(%d),stub!\n",iface,dolock); 154 return S_OK; 155 } 156 157 static const struct IClassFactoryVtbl mscorecf_vtbl = 158 { 159 mscorecf_QueryInterface, 160 mscorecf_AddRef, 161 mscorecf_Release, 162 mscorecf_CreateInstance, 163 mscorecf_LockServer 164 }; 165 166 HRESULT WINAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, 167 LPCWSTR pwszHostConfigFile, VOID *pReserved, 168 DWORD startupFlags, REFCLSID rclsid, 169 REFIID riid, LPVOID *ppv) 170 { 171 HRESULT ret; 172 ICLRRuntimeInfo *info; 173 174 TRACE("(%s, %s, %s, %p, %d, %s, %s, %p)\n", debugstr_w(pwszVersion), 175 debugstr_w(pwszBuildFlavor), debugstr_w(pwszHostConfigFile), pReserved, 176 startupFlags, debugstr_guid(rclsid), debugstr_guid(riid), ppv); 177 178 *ppv = NULL; 179 180 ret = get_runtime_info(NULL, pwszVersion, pwszHostConfigFile, startupFlags, 0, TRUE, &info); 181 182 if (SUCCEEDED(ret)) 183 { 184 ret = ICLRRuntimeInfo_GetInterface(info, rclsid, riid, ppv); 185 186 ICLRRuntimeInfo_Release(info); 187 } 188 189 return ret; 190 } 191 192 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 193 { 194 TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); 195 196 MSCOREE_hInstance = hinstDLL; 197 198 switch (fdwReason) 199 { 200 case DLL_WINE_PREATTACH: 201 return FALSE; /* prefer native version */ 202 case DLL_PROCESS_ATTACH: 203 runtimehost_init(); 204 DisableThreadLibraryCalls(hinstDLL); 205 break; 206 case DLL_PROCESS_DETACH: 207 expect_no_runtimes(); 208 if (lpvReserved) break; /* process is terminating */ 209 runtimehost_uninit(); 210 break; 211 } 212 return TRUE; 213 } 214 215 __int32 WINAPI _CorExeMain2(PBYTE ptrMemory, DWORD cntMemory, LPWSTR imageName, LPWSTR loaderName, LPWSTR cmdLine) 216 { 217 TRACE("(%p, %u, %s, %s, %s)\n", ptrMemory, cntMemory, debugstr_w(imageName), debugstr_w(loaderName), debugstr_w(cmdLine)); 218 FIXME("Directly running .NET applications not supported.\n"); 219 return -1; 220 } 221 222 void WINAPI CorExitProcess(int exitCode) 223 { 224 TRACE("(%x)\n", exitCode); 225 unload_all_runtimes(); 226 ExitProcess(exitCode); 227 } 228 229 VOID WINAPI _CorImageUnloading(PVOID imageBase) 230 { 231 TRACE("(%p): stub\n", imageBase); 232 } 233 234 HRESULT WINAPI _CorValidateImage(PVOID* imageBase, LPCWSTR imageName) 235 { 236 TRACE("(%p, %s): stub\n", imageBase, debugstr_w(imageName)); 237 return E_FAIL; 238 } 239 240 HRESULT WINAPI GetCORSystemDirectory(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength) 241 { 242 ICLRRuntimeInfo *info; 243 HRESULT ret; 244 245 TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength); 246 247 if (!dwLength || !pbuffer) 248 return E_POINTER; 249 250 ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info); 251 252 if (SUCCEEDED(ret)) 253 { 254 *dwLength = cchBuffer; 255 ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pbuffer, dwLength); 256 257 ICLRRuntimeInfo_Release(info); 258 } 259 260 return ret; 261 } 262 263 HRESULT WINAPI GetCORVersion(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength) 264 { 265 ICLRRuntimeInfo *info; 266 HRESULT ret; 267 268 TRACE("(%p, %d, %p)!\n", pbuffer, cchBuffer, dwLength); 269 270 if (!dwLength || !pbuffer) 271 return E_POINTER; 272 273 ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info); 274 275 if (SUCCEEDED(ret)) 276 { 277 *dwLength = cchBuffer; 278 ret = ICLRRuntimeInfo_GetVersionString(info, pbuffer, dwLength); 279 280 ICLRRuntimeInfo_Release(info); 281 } 282 283 return ret; 284 } 285 286 HRESULT WINAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile, 287 DWORD startupFlags, DWORD runtimeInfoFlags, LPWSTR pDirectory, DWORD dwDirectory, DWORD *dwDirectoryLength, 288 LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength) 289 { 290 HRESULT ret; 291 ICLRRuntimeInfo *info; 292 DWORD length_dummy; 293 294 TRACE("(%s, %s, %s, 0x%08x, 0x%08x, %p, 0x%08x, %p, %p, 0x%08x, %p)\n", debugstr_w(pExe), 295 debugstr_w(pwszVersion), debugstr_w(pConfigurationFile), startupFlags, runtimeInfoFlags, pDirectory, 296 dwDirectory, dwDirectoryLength, pVersion, cchBuffer, dwlength); 297 298 if (!dwDirectoryLength) dwDirectoryLength = &length_dummy; 299 300 if (!dwlength) dwlength = &length_dummy; 301 302 ret = get_runtime_info(pExe, pwszVersion, pConfigurationFile, startupFlags, runtimeInfoFlags, TRUE, &info); 303 304 if (SUCCEEDED(ret)) 305 { 306 *dwlength = cchBuffer; 307 ret = ICLRRuntimeInfo_GetVersionString(info, pVersion, dwlength); 308 309 if (SUCCEEDED(ret)) 310 { 311 if(pwszVersion) 312 pVersion[0] = pwszVersion[0]; 313 314 *dwDirectoryLength = dwDirectory; 315 ret = ICLRRuntimeInfo_GetRuntimeDirectory(info, pDirectory, dwDirectoryLength); 316 } 317 318 ICLRRuntimeInfo_Release(info); 319 } 320 321 return ret; 322 } 323 324 HRESULT WINAPI GetRequestedRuntimeVersion(LPWSTR pExe, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwlength) 325 { 326 TRACE("(%s, %p, %d, %p)\n", debugstr_w(pExe), pVersion, cchBuffer, dwlength); 327 328 if(!dwlength) 329 return E_POINTER; 330 331 return GetRequestedRuntimeInfo(pExe, NULL, NULL, 0, 0, NULL, 0, NULL, pVersion, cchBuffer, dwlength); 332 } 333 334 HRESULT WINAPI GetRealProcAddress(LPCSTR procname, void **ppv) 335 { 336 FIXME("(%s, %p)\n", debugstr_a(procname), ppv); 337 return CLR_E_SHIM_RUNTIMEEXPORT; 338 } 339 340 HRESULT WINAPI GetFileVersion(LPCWSTR szFilename, LPWSTR szBuffer, DWORD cchBuffer, DWORD *dwLength) 341 { 342 TRACE("(%s, %p, %d, %p)\n", debugstr_w(szFilename), szBuffer, cchBuffer, dwLength); 343 344 if (!szFilename || !dwLength) 345 return E_POINTER; 346 347 *dwLength = cchBuffer; 348 return CLRMetaHost_GetVersionFromFile(0, szFilename, szBuffer, dwLength); 349 } 350 351 HRESULT WINAPI LoadLibraryShim( LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE * phModDll) 352 { 353 HRESULT ret=S_OK; 354 WCHAR dll_filename[MAX_PATH]; 355 WCHAR version[MAX_PATH]; 356 static const WCHAR default_version[] = {'v','1','.','1','.','4','3','2','2',0}; 357 static const WCHAR slash[] = {'\\',0}; 358 DWORD dummy; 359 360 TRACE("(%p %s, %p, %p, %p)\n", szDllName, debugstr_w(szDllName), szVersion, pvReserved, phModDll); 361 362 if (!szDllName || !phModDll) 363 return E_POINTER; 364 365 if (!get_install_root(dll_filename)) 366 { 367 ERR("error reading registry key for installroot\n"); 368 dll_filename[0] = 0; 369 } 370 else 371 { 372 if (!szVersion) 373 { 374 ret = GetCORVersion(version, MAX_PATH, &dummy); 375 if (SUCCEEDED(ret)) 376 szVersion = version; 377 else 378 szVersion = default_version; 379 } 380 strcatW(dll_filename, szVersion); 381 strcatW(dll_filename, slash); 382 } 383 384 strcatW(dll_filename, szDllName); 385 386 *phModDll = LoadLibraryW(dll_filename); 387 388 return *phModDll ? S_OK : E_HANDLE; 389 } 390 391 HRESULT WINAPI LockClrVersion(FLockClrVersionCallback hostCallback, FLockClrVersionCallback *pBeginHostSetup, FLockClrVersionCallback *pEndHostSetup) 392 { 393 FIXME("(%p %p %p): stub\n", hostCallback, pBeginHostSetup, pEndHostSetup); 394 return S_OK; 395 } 396 397 HRESULT WINAPI CoInitializeCor(DWORD fFlags) 398 { 399 FIXME("(0x%08x): stub\n", fFlags); 400 return S_OK; 401 } 402 403 HRESULT WINAPI GetAssemblyMDImport(LPCWSTR szFileName, REFIID riid, IUnknown **ppIUnk) 404 { 405 FIXME("(%p %s, %s, %p): stub\n", szFileName, debugstr_w(szFileName), debugstr_guid(riid), *ppIUnk); 406 return ERROR_CALL_NOT_IMPLEMENTED; 407 } 408 409 HRESULT WINAPI GetVersionFromProcess(HANDLE hProcess, LPWSTR pVersion, DWORD cchBuffer, DWORD *dwLength) 410 { 411 FIXME("(%p, %p, %d, %p): stub\n", hProcess, pVersion, cchBuffer, dwLength); 412 return E_NOTIMPL; 413 } 414 415 HRESULT WINAPI LoadStringRCEx(LCID culture, UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet, int* pBufLen) 416 { 417 HRESULT res = S_OK; 418 if ((iBufLen <= 0) || !pBuffer) 419 return E_INVALIDARG; 420 pBuffer[0] = 0; 421 if (resId) { 422 FIXME("(%d, %x, %p, %d, %d, %p): semi-stub\n", culture, resId, pBuffer, iBufLen, bQuiet, pBufLen); 423 res = E_NOTIMPL; 424 } 425 else 426 res = E_FAIL; 427 if (pBufLen) 428 *pBufLen = lstrlenW(pBuffer); 429 return res; 430 } 431 432 HRESULT WINAPI LoadStringRC(UINT resId, LPWSTR pBuffer, int iBufLen, int bQuiet) 433 { 434 return LoadStringRCEx(-1, resId, pBuffer, iBufLen, bQuiet, NULL); 435 } 436 437 HRESULT WINAPI CorBindToRuntimeEx(LPWSTR szVersion, LPWSTR szBuildFlavor, DWORD nflags, REFCLSID rslsid, 438 REFIID riid, LPVOID *ppv) 439 { 440 HRESULT ret; 441 ICLRRuntimeInfo *info; 442 443 TRACE("%s %s %d %s %s %p\n", debugstr_w(szVersion), debugstr_w(szBuildFlavor), nflags, debugstr_guid( rslsid ), 444 debugstr_guid( riid ), ppv); 445 446 *ppv = NULL; 447 448 ret = get_runtime_info(NULL, szVersion, NULL, nflags, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info); 449 450 if (SUCCEEDED(ret)) 451 { 452 ret = ICLRRuntimeInfo_GetInterface(info, rslsid, riid, ppv); 453 454 ICLRRuntimeInfo_Release(info); 455 } 456 457 return ret; 458 } 459 460 HRESULT WINAPI CorBindToCurrentRuntime(LPCWSTR filename, REFCLSID rclsid, REFIID riid, LPVOID *ppv) 461 { 462 FIXME("(%s, %s, %s, %p): stub\n", debugstr_w(filename), debugstr_guid(rclsid), debugstr_guid(riid), ppv); 463 return E_NOTIMPL; 464 } 465 466 STDAPI ClrCreateManagedInstance(LPCWSTR pTypeName, REFIID riid, void **ppObject) 467 { 468 HRESULT ret; 469 ICLRRuntimeInfo *info; 470 RuntimeHost *host; 471 MonoObject *obj; 472 IUnknown *unk; 473 474 TRACE("(%s,%s,%p)\n", debugstr_w(pTypeName), debugstr_guid(riid), ppObject); 475 476 /* FIXME: How to determine which runtime version to use? */ 477 ret = get_runtime_info(NULL, NULL, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, TRUE, &info); 478 479 if (SUCCEEDED(ret)) 480 { 481 ret = ICLRRuntimeInfo_GetRuntimeHost(info, &host); 482 483 ICLRRuntimeInfo_Release(info); 484 } 485 486 if (SUCCEEDED(ret)) 487 ret = RuntimeHost_CreateManagedInstance(host, pTypeName, NULL, &obj); 488 489 if (SUCCEEDED(ret)) 490 ret = RuntimeHost_GetIUnknownForObject(host, obj, &unk); 491 492 if (SUCCEEDED(ret)) 493 { 494 ret = IUnknown_QueryInterface(unk, riid, ppObject); 495 IUnknown_Release(unk); 496 } 497 498 return ret; 499 } 500 501 BOOL WINAPI StrongNameSignatureVerification(LPCWSTR filename, DWORD inFlags, DWORD* pOutFlags) 502 { 503 FIXME("(%s, 0x%X, %p): stub\n", debugstr_w(filename), inFlags, pOutFlags); 504 return FALSE; 505 } 506 507 BOOL WINAPI StrongNameSignatureVerificationEx(LPCWSTR filename, BOOL forceVerification, BOOL* pVerified) 508 { 509 FIXME("(%s, %u, %p): stub\n", debugstr_w(filename), forceVerification, pVerified); 510 return FALSE; 511 } 512 513 HRESULT WINAPI CreateConfigStream(LPCWSTR filename, IStream **stream) 514 { 515 FIXME("(%s, %p): stub\n", debugstr_w(filename), stream); 516 return E_NOTIMPL; 517 } 518 519 HRESULT WINAPI CreateDebuggingInterfaceFromVersion(int nDebugVersion, LPCWSTR version, IUnknown **ppv) 520 { 521 const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0}; 522 HRESULT hr = E_FAIL; 523 ICLRRuntimeInfo *runtimeinfo; 524 525 if(nDebugVersion < 1 || nDebugVersion > 4) 526 return E_INVALIDARG; 527 528 TRACE("(%d %s, %p): stub\n", nDebugVersion, debugstr_w(version), ppv); 529 530 if(!ppv) 531 return E_INVALIDARG; 532 533 *ppv = NULL; 534 535 if(strcmpW(version, v2_0) != 0) 536 { 537 FIXME("Currently .NET Version '%s' not support.\n", debugstr_w(version)); 538 return E_INVALIDARG; 539 } 540 541 if(nDebugVersion != 3) 542 return E_INVALIDARG; 543 544 hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)&runtimeinfo); 545 if(hr == S_OK) 546 { 547 hr = ICLRRuntimeInfo_GetInterface(runtimeinfo, &CLSID_CLRDebuggingLegacy, &IID_ICorDebug, (void**)ppv); 548 549 ICLRRuntimeInfo_Release(runtimeinfo); 550 } 551 552 if(!*ppv) 553 return E_FAIL; 554 555 return hr; 556 } 557 558 HRESULT WINAPI CLRCreateInstance(REFCLSID clsid, REFIID riid, LPVOID *ppInterface) 559 { 560 TRACE("(%s,%s,%p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppInterface); 561 562 if (IsEqualGUID(clsid, &CLSID_CLRMetaHost)) 563 return CLRMetaHost_CreateInstance(riid, ppInterface); 564 565 FIXME("not implemented for class %s\n", debugstr_guid(clsid)); 566 567 return CLASS_E_CLASSNOTAVAILABLE; 568 } 569 570 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) 571 { 572 mscorecf *This; 573 HRESULT hr; 574 575 TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 576 577 if(!ppv) 578 return E_INVALIDARG; 579 580 This = HeapAlloc(GetProcessHeap(), 0, sizeof(mscorecf)); 581 582 This->IClassFactory_iface.lpVtbl = &mscorecf_vtbl; 583 This->pfnCreateInstance = &create_monodata; 584 This->ref = 1; 585 This->clsid = *rclsid; 586 587 hr = IClassFactory_QueryInterface( &This->IClassFactory_iface, riid, ppv ); 588 IClassFactory_Release(&This->IClassFactory_iface); 589 590 return hr; 591 } 592 593 HRESULT WINAPI DllRegisterServer(void) 594 { 595 return __wine_register_resources( MSCOREE_hInstance ); 596 } 597 598 HRESULT WINAPI DllUnregisterServer(void) 599 { 600 return __wine_unregister_resources( MSCOREE_hInstance ); 601 } 602 603 HRESULT WINAPI DllCanUnloadNow(VOID) 604 { 605 return S_FALSE; 606 } 607 608 void WINAPI CoEEShutDownCOM(void) 609 { 610 FIXME("stub.\n"); 611 } 612 613 INT WINAPI ND_RU1( const void *ptr, INT offset ) 614 { 615 return *((const BYTE *)ptr + offset); 616 } 617 618 INT WINAPI ND_RI2( const void *ptr, INT offset ) 619 { 620 return *(const SHORT *)((const BYTE *)ptr + offset); 621 } 622 623 INT WINAPI ND_RI4( const void *ptr, INT offset ) 624 { 625 return *(const INT *)((const BYTE *)ptr + offset); 626 } 627 628 INT64 WINAPI ND_RI8( const void *ptr, INT offset ) 629 { 630 return *(const INT64 *)((const BYTE *)ptr + offset); 631 } 632 633 void WINAPI ND_WU1( void *ptr, INT offset, BYTE val ) 634 { 635 *((BYTE *)ptr + offset) = val; 636 } 637 638 void WINAPI ND_WI2( void *ptr, INT offset, SHORT val ) 639 { 640 *(SHORT *)((BYTE *)ptr + offset) = val; 641 } 642 643 void WINAPI ND_WI4( void *ptr, INT offset, INT val ) 644 { 645 *(INT *)((BYTE *)ptr + offset) = val; 646 } 647 648 void WINAPI ND_WI8( void *ptr, INT offset, INT64 val ) 649 { 650 *(INT64 *)((BYTE *)ptr + offset) = val; 651 } 652 653 void WINAPI ND_CopyObjDst( const void *src, void *dst, INT offset, INT size ) 654 { 655 memcpy( (BYTE *)dst + offset, src, size ); 656 } 657 658 void WINAPI ND_CopyObjSrc( const void *src, INT offset, void *dst, INT size ) 659 { 660 memcpy( dst, (const BYTE *)src + offset, size ); 661 } 662