Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1523 lines
42 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1996-1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dplpack.c
  6. * Content: Methods for packing/unpacking structures
  7. *
  8. * History:
  9. * Date By Reason
  10. * ======= ======= ======
  11. * 5/31/96 myronth Created it
  12. * 6/26/96 kipo added support for DPADDRESS.
  13. * 7/13/96 kipo Bug fix - added (LPBYTE) cast to lpConnPack (address calc)
  14. * in PRV_UnpackageDPLCONNECTIONAnsi()
  15. * 11/20/96 myronth Removed packing for DPTRANSPORT
  16. * 12/12/96 myronth Added DPLCONNECTION structure validation
  17. * 2/12/97 myronth Mass DX5 changes
  18. * 4/3/97 myronth Changed STRLEN's to WSTRLEN's from dplaypr.h
  19. * 5/8/97 myronth Changed most packing functions to use the packed
  20. * conn header, added pointer fixup function, Moved
  21. * PRV_ConvertDPLCONNECTIONToUnicode from convert.c
  22. * 9/29/97 myronth Fixed DPLCONNECTION package size bug (#12475)
  23. * 12/2/97 myronth Made SessionDesc mandatory in DPLCONNECTION (#15529)
  24. * 7/08/98 a-peterz Allow for MBCS for ANSI string sizes. ManBug 16299
  25. * 2/10/99 aarono add support for application launcher
  26. * 10/22/99 aarono added support for application flags
  27. * 01/21/00 aarono added support for DPSESSION_ALLOWVOICERETRO flag
  28. ***************************************************************************/
  29. #include "dplobpr.h"
  30. //--------------------------------------------------------------------------
  31. //
  32. // Functions
  33. //
  34. //--------------------------------------------------------------------------
  35. #undef DPF_MODNAME
  36. #define DPF_MODNAME "PRV_GetDPLCONNECTIONPackageSize"
  37. void PRV_GetDPLCONNECTIONPackageSize(LPDPLCONNECTION lpConn,
  38. LPDWORD lpdwUnicode, LPDWORD lpdwAnsi)
  39. {
  40. DWORD dwSize;
  41. DWORD dwStringSize = 0;
  42. DWORD dwStringSizeA = 0;
  43. LPDPSESSIONDESC2 lpsd = NULL;
  44. LPDPNAME lpn = NULL;
  45. DPF(7, "Entering PRV_GetDPLCONNECTIONPackageSize");
  46. DPF(9, "Parameters: 0x%08x, 0x%08x, 0x%08x",
  47. lpConn, lpdwUnicode, lpdwAnsi);
  48. ASSERT(lpConn);
  49. // First calculate the size of the structures
  50. dwSize = sizeof(DPLCONNECTION);
  51. // Add the size of the SessionDesc and Name structs
  52. if(lpConn->lpSessionDesc)
  53. {
  54. dwSize += sizeof(DPSESSIONDESC2);
  55. lpsd = lpConn->lpSessionDesc;
  56. if(lpsd->lpszSessionName)
  57. dwStringSize += WSTRLEN(lpsd->lpszSessionName);
  58. if(lpsd->lpszPassword)
  59. dwStringSize += WSTRLEN(lpsd->lpszPassword);
  60. // only compute ANSI size if needed. Macro handles NULLS; includes terminator
  61. if(lpdwAnsi)
  62. {
  63. dwStringSizeA += WSTR_ANSILENGTH(lpsd->lpszSessionName);
  64. dwStringSizeA += WSTR_ANSILENGTH(lpsd->lpszPassword);
  65. }
  66. }
  67. if(lpConn->lpPlayerName)
  68. {
  69. dwSize += sizeof(DPNAME);
  70. lpn = lpConn->lpPlayerName;
  71. if(lpn->lpszShortName)
  72. dwStringSize += WSTRLEN(lpn->lpszShortName);
  73. if(lpn->lpszLongName)
  74. dwStringSize += WSTRLEN(lpn->lpszLongName);
  75. // only compute ANSI size if needed. Macro handles NULLS; includes terminator
  76. if(lpdwAnsi)
  77. {
  78. dwStringSizeA += WSTR_ANSILENGTH(lpn->lpszShortName);
  79. dwStringSizeA += WSTR_ANSILENGTH(lpn->lpszLongName);
  80. }
  81. }
  82. // Add the size of the SP-specific data
  83. if(lpConn->lpAddress)
  84. dwSize += lpConn->dwAddressSize;
  85. // Now add in the size of the packed structure header
  86. dwSize += sizeof(DPLOBBYI_PACKEDCONNHEADER);
  87. // Fill in the output variables
  88. if(lpdwAnsi)
  89. *lpdwAnsi = dwSize + dwStringSizeA;
  90. if(lpdwUnicode)
  91. *lpdwUnicode = dwSize + (dwStringSize * sizeof(WCHAR));
  92. } // PRV_GetDPLCONNECTIONPackageSize
  93. #undef DPF_MODNAME
  94. #define DPF_MODNAME "PRV_PackageDPLCONNECTION"
  95. HRESULT PRV_PackageDPLCONNECTION(LPDPLCONNECTION lpConn, LPVOID lpBuffer,
  96. BOOL bHeader)
  97. {
  98. LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
  99. LPDPLCONNECTION lpConnPacked = NULL;
  100. LPDPSESSIONDESC2 lpsd = NULL,
  101. lpsdPacked = NULL;
  102. LPDPNAME lpn = NULL,
  103. lpnPacked = NULL;
  104. LPBYTE lpStart, lpCurrent;
  105. DWORD dwSizeAnsi,
  106. dwSizeUnicode,
  107. dwTemp;
  108. DPF(7, "Entering PRV_PackageDPLCONNECTION");
  109. DPF(9, "Parameters: 0x%08x, 0x%08x, %lu", lpConn, lpBuffer, bHeader);
  110. ASSERT(lpConn);
  111. // If the bHeader flag is set, we want to copy the packed header into the
  112. // buffer first. If it is not, we only want the packed DPLCONNECTION struct
  113. if(bHeader)
  114. {
  115. PRV_GetDPLCONNECTIONPackageSize(lpConn, &dwSizeUnicode, &dwSizeAnsi);
  116. lpHeader = (LPDPLOBBYI_PACKEDCONNHEADER)lpBuffer;
  117. lpHeader->dwUnicodeSize = dwSizeUnicode;
  118. lpHeader->dwAnsiSize = dwSizeAnsi;
  119. lpStart = (LPBYTE)lpBuffer + sizeof(DPLOBBYI_PACKEDCONNHEADER);
  120. }
  121. else
  122. {
  123. lpStart = lpBuffer;
  124. }
  125. // Copy in the structures & store the offsets
  126. memcpy(lpStart, lpConn, sizeof(DPLCONNECTION));
  127. lpConnPacked = (LPDPLCONNECTION)lpStart;
  128. lpCurrent = lpStart + sizeof(DPLCONNECTION);
  129. if(lpConn->lpSessionDesc)
  130. {
  131. lpsd = lpConn->lpSessionDesc;
  132. lpsdPacked = (LPDPSESSIONDESC2)lpCurrent;
  133. if(lpsdPacked->dwSize==sizeof(DPSESSIONDESC2)){
  134. // we are over-riding and existing session descriptor, don't let
  135. // the session flag for the retrofit get over-riden
  136. lpsd->dwFlags |= (lpsdPacked->dwFlags & DPSESSION_ALLOWVOICERETRO);
  137. }
  138. memcpy(lpCurrent, lpsd, sizeof(DPSESSIONDESC2));
  139. (DWORD_PTR)lpConnPacked->lpSessionDesc = (DWORD_PTR)(lpCurrent - lpStart);
  140. lpCurrent += sizeof(DPSESSIONDESC2);
  141. }
  142. if(lpConn->lpPlayerName)
  143. {
  144. lpn = lpConn->lpPlayerName;
  145. memcpy(lpCurrent, lpn, sizeof(DPNAME));
  146. lpnPacked = (LPDPNAME)lpCurrent;
  147. (DWORD_PTR)lpConnPacked->lpPlayerName = (DWORD_PTR)(lpCurrent - lpStart);
  148. lpCurrent += sizeof(DPNAME);
  149. }
  150. // Copy in the strings in the SessionDesc and store the offset of the
  151. // string from lpStart (relative offset in our package) in the pointer
  152. // for the string in the SessionDesc structure. We will use this
  153. // value to unpack and fix up the pointers during GetConnectionSettings
  154. if(lpsd)
  155. {
  156. if(lpsd->lpszSessionName)
  157. {
  158. // Copy the string
  159. dwTemp = WSTRLEN(lpsd->lpszSessionName) * sizeof(WCHAR);
  160. memcpy(lpCurrent, lpsd->lpszSessionName, dwTemp);
  161. // Store the offset
  162. lpsdPacked->lpszSessionName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
  163. lpCurrent += dwTemp;
  164. }
  165. if(lpsd->lpszPassword)
  166. {
  167. // Copy the string
  168. dwTemp = WSTRLEN(lpsd->lpszPassword) * sizeof(WCHAR);
  169. memcpy(lpCurrent, lpsd->lpszPassword, dwTemp);
  170. // Store the offset
  171. lpsdPacked->lpszPassword = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
  172. lpCurrent += dwTemp;
  173. }
  174. }
  175. // Copy in the strings in the DPName struct and store the offset of the
  176. // string from lpStart (relative offset in our package) in the pointer
  177. // for the string in the SessionDesc structure. We will use this
  178. // value to unpack and fix up the pointers during GetConnectionSettings
  179. if(lpn)
  180. {
  181. if(lpn->lpszShortName)
  182. {
  183. // Copy the string
  184. dwTemp = WSTRLEN(lpn->lpszShortName) * sizeof(WCHAR);
  185. memcpy(lpCurrent, lpn->lpszShortName, dwTemp);
  186. // Store the offset
  187. lpnPacked->lpszShortName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
  188. lpCurrent += dwTemp;
  189. }
  190. if(lpn->lpszLongName)
  191. {
  192. // Copy the string
  193. dwTemp = WSTRLEN(lpn->lpszLongName) * sizeof(WCHAR);
  194. memcpy(lpCurrent, lpn->lpszLongName, dwTemp);
  195. // Store the offset
  196. lpnPacked->lpszLongName = (LPWSTR)(DWORD_PTR)(lpCurrent - lpStart);
  197. lpCurrent += dwTemp;
  198. }
  199. }
  200. // Copy in the SP-specific data
  201. if(lpConn->lpAddress)
  202. {
  203. // Copy the data
  204. memcpy(lpCurrent, lpConn->lpAddress, lpConn->dwAddressSize);
  205. // Store the offset
  206. ((LPDPLCONNECTION)lpStart)->lpAddress = (LPVOID)(DWORD_PTR)(lpCurrent - lpStart);
  207. }
  208. return DP_OK;
  209. } // PRV_PackageDPLCONNECTION
  210. #define MAX_DPLCONNECTIONBUFFERSIZE (MAX_APPDATABUFFERSIZE -sizeof(DPLOBBYI_CONNCONTROL))
  211. #undef DPF_MODNAME
  212. #define DPF_MODNAME "PRV_UnpackageDPLCONNECTIONUnicode"
  213. // NOTE : really need to define a WIRE LPDPLCONNECTION so that
  214. // we can crack it that way. This will allow compile, until
  215. // we can test on Win64, there is no way to verify cracking
  216. // the packet, so I've deffered this work until then AO 11/10/98
  217. // not bringing DP4 to Win64 AO 04/03/2001
  218. HRESULT PRV_UnpackageDPLCONNECTIONUnicode(LPVOID lpData, LPVOID lpPackage)
  219. {
  220. LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
  221. LPDPLCONNECTION lpConn = NULL;
  222. LPDPSESSIONDESC2 lpsd = NULL;
  223. LPDPNAME lpn = NULL;
  224. LPBYTE lpPackCur, lpDataStart;
  225. DWORD_PTR dwSize;
  226. PCHAR pBufStart=(PCHAR)lpPackage;
  227. PCHAR pBufEnd=(PCHAR)lpPackage+MAX_DPLCONNECTIONBUFFERSIZE-3;
  228. HRESULT hr=DP_OK;
  229. // SECURITY: ensure NULL termination for string scanning.
  230. ((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE-1]=0;
  231. ((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE-2]=0;
  232. DPF(7, "Entering PRV_UnpackageDPLCONNECTIONUnicode");
  233. DPF(9, "Parameters: 0x%08x, 0x%08x", lpData, lpPackage);
  234. // If we're Unicode, all we need to do is copy the entire package
  235. // and fix up the pointers
  236. lpHeader = (LPDPLOBBYI_PACKEDCONNHEADER)lpPackage;
  237. dwSize = lpHeader->dwUnicodeSize;
  238. lpPackCur = ((LPBYTE)lpPackage) + sizeof(DPLOBBYI_PACKEDCONNHEADER);
  239. lpDataStart = lpData;
  240. // Copy the data
  241. memcpy(lpData, lpPackCur, (DWORD)dwSize);
  242. // Fix up the pointers -- the offset of every element relative to
  243. // the start of lpConn is stored in the pointer for the element.
  244. // So all we have to do to fix up the pointers is calculate it from
  245. // the given offset + the value of lpConn.
  246. lpConn = (LPDPLCONNECTION)lpData;
  247. if(lpConn->lpSessionDesc)
  248. {
  249. if((UINT)lpConn->lpSessionDesc > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPSESSIONDESC2)))
  250. {
  251. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  252. hr=DPERR_GENERIC;
  253. goto err_exit;
  254. }
  255. dwSize = (DWORD_PTR)lpConn->lpSessionDesc;
  256. lpsd = lpConn->lpSessionDesc = (LPDPSESSIONDESC2)(lpDataStart + dwSize);
  257. // Now do the same for the strings
  258. if(lpsd->lpszSessionName)
  259. {
  260. if((UINT)lpsd->lpszSessionName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  261. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  262. hr=DPERR_GENERIC;
  263. goto err_exit;
  264. }
  265. lpsd->lpszSessionName = (LPWSTR)(lpDataStart +
  266. ((DWORD_PTR)lpsd->lpszSessionName));
  267. }
  268. if(lpsd->lpszPassword)
  269. {
  270. if((UINT)lpsd->lpszPassword > MAX_DPLCONNECTIONBUFFERSIZE-3){
  271. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  272. hr=DPERR_GENERIC;
  273. goto err_exit;
  274. }
  275. lpsd->lpszPassword = (LPWSTR)(lpDataStart +
  276. ((DWORD_PTR)lpsd->lpszPassword));
  277. }
  278. }
  279. if(lpConn->lpPlayerName)
  280. {
  281. if((UINT)lpConn->lpPlayerName > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPNAME)))
  282. {
  283. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  284. hr=DPERR_GENERIC;
  285. goto err_exit;
  286. }
  287. dwSize = (DWORD_PTR)lpConn->lpPlayerName;
  288. lpn = lpConn->lpPlayerName = (LPDPNAME)(lpDataStart + dwSize);
  289. // Now do the same for the strings
  290. if(lpn->lpszShortName)
  291. {
  292. if((UINT)lpn->lpszShortName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  293. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  294. hr=DPERR_GENERIC;
  295. goto err_exit;
  296. }
  297. lpn->lpszShortName = (LPWSTR)(lpDataStart +
  298. ((DWORD_PTR)lpn->lpszShortName));
  299. }
  300. if(lpn->lpszLongName)
  301. {
  302. if((UINT)lpn->lpszLongName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  303. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  304. hr=DPERR_GENERIC;
  305. goto err_exit;
  306. }
  307. lpn->lpszLongName = (LPWSTR)(lpDataStart +
  308. ((DWORD_PTR)lpn->lpszLongName));
  309. }
  310. }
  311. // Fix the SPData pointer
  312. if(lpConn->lpAddress)
  313. {
  314. if((UINT)lpConn->lpAddress > MAX_DPLCONNECTIONBUFFERSIZE-(sizeof(DPADDRESS)) ||
  315. (UINT)lpConn->lpAddress+lpConn->dwAddressSize > MAX_DPLCONNECTIONBUFFERSIZE-3)
  316. {
  317. DPF(4,"SECURITY WARN: Invalid offset in shared memory");
  318. hr=DPERR_GENERIC;
  319. goto err_exit;
  320. }
  321. lpConn->lpAddress = lpDataStart + ((DWORD_PTR)lpConn->lpAddress);
  322. }
  323. return DP_OK;
  324. err_exit:
  325. return hr;
  326. } // PRV_UnpackageDPLCONNECTIONUnicode
  327. #undef DPF_MODNAME
  328. #define DPF_MODNAME "PRV_UnpackageDPLCONNECTIONAnsi"
  329. HRESULT PRV_UnpackageDPLCONNECTIONAnsi(LPVOID lpData, LPVOID lpPackage)
  330. {
  331. LPDPLOBBYI_PACKEDCONNHEADER lpHeader = NULL;
  332. LPDPLCONNECTION lpConnData, lpConnPack;
  333. LPDPSESSIONDESC2 lpsdData = NULL,
  334. lpsdPack = NULL;
  335. LPDPNAME lpnData = NULL,
  336. lpnPack = NULL;
  337. LPBYTE lpDataCur, lpPackCur;
  338. DWORD dwTemp;
  339. LPWSTR lpszTemp;
  340. HRESULT hr=DP_OK;
  341. // SECURITY: ensure NULL termination for string scanning.
  342. ((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE -1]=0;
  343. ((LPBYTE)lpPackage)[MAX_DPLCONNECTIONBUFFERSIZE -2]=0;
  344. DPF(7, "Entering PRV_UnpackageDPLCONNECTIONAnsi");
  345. DPF(9, "Parameters: 0x%08x, 0x%08x", lpData, lpPackage);
  346. // If we're Ansi, we need to do is copy the structures, convert
  347. // and copy the strings, and fix up all the pointers
  348. lpPackCur = ((LPBYTE)lpPackage) + sizeof(DPLOBBYI_PACKEDCONNHEADER);
  349. lpDataCur = lpData;
  350. // First copy the main structures
  351. dwTemp = sizeof(DPLCONNECTION);
  352. memcpy(lpDataCur, lpPackCur, dwTemp);
  353. lpConnData = (LPDPLCONNECTION)lpDataCur;
  354. lpConnPack = (LPDPLCONNECTION)lpPackCur;
  355. lpDataCur += dwTemp;
  356. lpPackCur += dwTemp;
  357. if(lpConnData->lpSessionDesc)
  358. {
  359. dwTemp = sizeof(DPSESSIONDESC2);
  360. memcpySecureS(lpDataCur, lpPackCur, sizeof(DPSESSIONDESC2),lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid Session Description in shared memory",hr=DPERR_GENERIC,err_exit);
  361. lpsdData = lpConnData->lpSessionDesc = (LPDPSESSIONDESC2)lpDataCur;
  362. lpsdPack = (LPDPSESSIONDESC2)lpPackCur;
  363. lpDataCur += dwTemp;
  364. lpPackCur += dwTemp;
  365. }
  366. if(lpConnData->lpPlayerName)
  367. {
  368. dwTemp = sizeof(DPNAME);
  369. memcpySecureS(lpDataCur, lpPackCur, sizeof(DPNAME),lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid DPNAME in shared memory",hr=DPERR_GENERIC,err_exit);
  370. lpnData = lpConnData->lpPlayerName = (LPDPNAME)lpDataCur;
  371. lpnPack = (LPDPNAME)lpPackCur;
  372. lpDataCur += dwTemp;
  373. lpPackCur += dwTemp;
  374. }
  375. // Copy the strings & fix up the pointers
  376. if(lpsdData)
  377. {
  378. if(lpsdData->lpszSessionName)
  379. {
  380. if((UINT)lpsdData->lpszSessionName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  381. DPF(4,"SECURITY WARN: Invalid Session Name in shared memory");
  382. hr=DPERR_GENERIC;
  383. goto err_exit;
  384. }
  385. lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpsdPack->lpszSessionName);
  386. dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
  387. WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
  388. lpsdData->lpszSessionNameA = (LPSTR)lpDataCur;
  389. lpDataCur += dwTemp;
  390. }
  391. if(lpsdData->lpszPassword)
  392. {
  393. if((UINT)lpsdData->lpszPassword > MAX_DPLCONNECTIONBUFFERSIZE-3){
  394. DPF(4,"SECURITY WARN: Invalid Password in shared memory");
  395. hr=DPERR_GENERIC;
  396. goto err_exit;
  397. }
  398. lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpsdPack->lpszPassword);
  399. dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
  400. WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
  401. lpsdData->lpszPasswordA = (LPSTR)lpDataCur;
  402. lpDataCur += dwTemp;
  403. }
  404. }
  405. if(lpnData)
  406. {
  407. if(lpnData->lpszShortName)
  408. {
  409. if((UINT)lpnData->lpszShortName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  410. DPF(4,"SECURITY WARN: Invalid Short Name in shared memory");
  411. hr=DPERR_GENERIC;
  412. goto err_exit;
  413. }
  414. lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpnPack->lpszShortName);
  415. dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
  416. WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
  417. lpnData->lpszShortNameA = (LPSTR)lpDataCur;
  418. lpDataCur += dwTemp;
  419. }
  420. if(lpnData->lpszLongName)
  421. {
  422. if((UINT)lpnData->lpszLongName > MAX_DPLCONNECTIONBUFFERSIZE-3){
  423. DPF(4,"SECURITY WARN: Invalid Long Name in shared memory");
  424. hr=DPERR_GENERIC;
  425. goto err_exit;
  426. }
  427. lpszTemp = (LPWSTR)((LPBYTE)lpConnPack + (DWORD_PTR)lpnPack->lpszLongName);
  428. dwTemp = WideToAnsi(NULL, lpszTemp, 0); // size includes terminator
  429. WideToAnsi((LPSTR)lpDataCur, lpszTemp, dwTemp);
  430. lpnData->lpszLongNameA = (LPSTR)lpDataCur;
  431. lpDataCur += dwTemp;
  432. }
  433. }
  434. // Copy in the SPData & fix up the pointer
  435. if(lpConnData->lpAddress)
  436. {
  437. lpPackCur = ((LPBYTE)lpConnPack) + (DWORD_PTR)lpConnPack->lpAddress;
  438. memcpySecureS(lpDataCur, lpPackCur, lpConnPack->dwAddressSize,lpPackage,MAX_DPLCONNECTIONBUFFERSIZE,"SECURITY WARN: Invalid ADDRESS in shared memory",hr=DPERR_GENERIC,err_exit);
  439. lpConnData->lpAddress = lpDataCur;
  440. }
  441. return DP_OK;
  442. err_exit:
  443. return hr;
  444. } // PRV_UnpackageDPLCONNECTIONAnsi
  445. #undef DPF_MODNAME
  446. #define DPF_MODNAME "PRV_ValidateDPLCONNECTION"
  447. HRESULT PRV_ValidateDPLCONNECTION(LPDPLCONNECTION lpConn, BOOL bAnsi)
  448. {
  449. LPDPSESSIONDESC2 lpsd = NULL;
  450. LPDPNAME lpn = NULL;
  451. DPF(7, "Entering PRV_ValidateDPLCONNECTION");
  452. DPF(9, "Parameters: 0x%08x, %lu", lpConn, bAnsi);
  453. TRY
  454. {
  455. // Validate the connection structure itself
  456. if(!VALID_DPLOBBY_CONNECTION(lpConn))
  457. {
  458. DPF_ERR("Invalid DPLCONNECTION structure");
  459. return DPERR_INVALIDPARAMS;
  460. }
  461. // Validate the flags
  462. if(lpConn->dwFlags & ~(DPLCONNECTION_CREATESESSION | DPLCONNECTION_JOINSESSION))
  463. {
  464. DPF_ERR("Invalid flags exist in the dwFlags member of the DPLCONNECTION structure");
  465. return DPERR_INVALIDFLAGS;
  466. }
  467. // Validate the SessionDesc structure
  468. if(lpConn->lpSessionDesc)
  469. {
  470. lpsd = lpConn->lpSessionDesc;
  471. // Validate the structure itself
  472. if(!VALID_READ_DPSESSIONDESC2(lpsd))
  473. {
  474. DPF_ERR("Invalid DPSESSIONDESC2 structure in DPLCONNECTION structure");
  475. return DPERR_INVALIDPARAMS;
  476. }
  477. // Validate the SessionName string
  478. if(lpsd->lpszSessionName)
  479. {
  480. if(!VALID_READ_PTR(lpsd->lpszSessionName, (bAnsi ?
  481. strlen(lpsd->lpszSessionNameA) : WSTRLEN_BYTES(lpsd->lpszSessionName))))
  482. {
  483. DPF_ERR("Invalid SessionName string in DPLCONNECTION structure");
  484. return DPERR_INVALIDPARAMS;
  485. }
  486. }
  487. // Validate the Password string
  488. if(lpsd->lpszPassword)
  489. {
  490. if(!VALID_READ_PTR(lpsd->lpszPassword, (bAnsi ?
  491. strlen(lpsd->lpszPasswordA) : WSTRLEN_BYTES(lpsd->lpszPassword))))
  492. {
  493. DPF_ERR("Invalid Password string in DPLCONNECTION structure");
  494. return DPERR_INVALIDPARAMS;
  495. }
  496. }
  497. }
  498. else
  499. {
  500. DPF_ERR("Invalid SessionDesc pointer in DPLCONNECTION structure");
  501. return DPERR_INVALIDPARAMS;
  502. }
  503. // Validate the Name structure
  504. if(lpConn->lpPlayerName)
  505. {
  506. lpn = lpConn->lpPlayerName;
  507. if(!VALID_READ_DPNAME_PTR(lpn))
  508. {
  509. DPF_ERR("Invalid DPNAME structure in DPLCONNECTION structure");
  510. return DPERR_INVALIDPARAMS;
  511. }
  512. // Validate the ShortName string
  513. if(lpn->lpszShortName)
  514. {
  515. if(!VALID_READ_PTR(lpn->lpszShortName, (bAnsi ?
  516. strlen(lpn->lpszShortNameA) : WSTRLEN_BYTES(lpn->lpszShortName))))
  517. {
  518. DPF_ERR("Invalid ShortName string in DPLCONNECTION structure");
  519. return DPERR_INVALIDPARAMS;
  520. }
  521. }
  522. // Validate the LongName string
  523. if(lpn->lpszLongName)
  524. {
  525. if(!VALID_READ_PTR(lpn->lpszLongName, (bAnsi ?
  526. strlen(lpn->lpszLongNameA) : WSTRLEN_BYTES(lpn->lpszLongName))))
  527. {
  528. DPF_ERR("Invalid LongName string in DPLCONNECTION structure");
  529. return DPERR_INVALIDPARAMS;
  530. }
  531. }
  532. }
  533. // Validate the DPADDRESS structure
  534. if(lpConn->lpAddress)
  535. {
  536. if(!VALID_READ_PTR(lpConn->lpAddress, lpConn->dwAddressSize))
  537. {
  538. DPF_ERR("Invalid lpAddress in DPLCONNECTION structure");
  539. return DPERR_INVALIDPARAMS;
  540. }
  541. }
  542. }
  543. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  544. {
  545. DPF_ERR( "Exception encountered validating parameters" );
  546. return DPERR_INVALIDPARAMS;
  547. }
  548. return DP_OK;
  549. } // PRV_ValidateDPLCONNECTION
  550. #undef DPF_MODNAME
  551. #define DPF_MODNAME "PRV_ConvertDPLCONNECTIONToUnicode"
  552. HRESULT PRV_ConvertDPLCONNECTIONToUnicode(LPDPLCONNECTION lpConnA,
  553. LPDPLCONNECTION * lplpConnW)
  554. {
  555. LPDPLCONNECTION lpConnW = NULL;
  556. LPDPSESSIONDESC2 lpsdW = NULL, lpsdA;
  557. LPDPNAME lpnW = NULL, lpnA;
  558. LPWSTR lpwszSessionName = NULL;
  559. LPWSTR lpwszPassword = NULL;
  560. LPWSTR lpwszLongName = NULL;
  561. LPWSTR lpwszShortName = NULL;
  562. HRESULT hr = DP_OK;
  563. DPF(7, "Entering PRV_ConvertDPLCONNECTIONToUnicode");
  564. DPF(9, "Parameters: 0x%08x, 0x%08x", lpConnA, lplpConnW);
  565. ASSERT(lpConnA);
  566. ASSERT(lplpConnW);
  567. // Allocate memory for the DPLCONNECTION structure
  568. lpConnW = DPMEM_ALLOC(sizeof(DPLCONNECTION));
  569. if(!lpConnW)
  570. {
  571. DPF_ERR("Unable to allocate memory for temporary Unicode DPLCONNECTION struct");
  572. hr = DPERR_OUTOFMEMORY;
  573. goto ERROR_CONVERT_DPLCONNECTION;
  574. }
  575. // If we need a SessionDesc struct, allocate one
  576. if(lpConnA->lpSessionDesc)
  577. {
  578. lpsdW = DPMEM_ALLOC(sizeof(DPSESSIONDESC2));
  579. if(!lpsdW)
  580. {
  581. DPF_ERR("Unable to allocate memory for temporary Unicode DPSESSIONDESC struct");
  582. hr = DPERR_OUTOFMEMORY;
  583. goto ERROR_CONVERT_DPLCONNECTION;
  584. }
  585. }
  586. // If we need a DPName struct, allocate one
  587. if(lpConnA->lpPlayerName)
  588. {
  589. lpnW = DPMEM_ALLOC(sizeof(DPNAME));
  590. if(!lpnW)
  591. {
  592. DPF_ERR("Unable to allocate memory for temporary Unicode DPNAME struct");
  593. hr = DPERR_OUTOFMEMORY;
  594. goto ERROR_CONVERT_DPLCONNECTION;
  595. }
  596. }
  597. // Copy the fixed size members of the structures
  598. memcpy(lpConnW, lpConnA, sizeof(DPLCONNECTION));
  599. if(lpsdW)
  600. memcpy(lpsdW, lpConnA->lpSessionDesc, sizeof(DPSESSIONDESC2));
  601. if(lpnW)
  602. memcpy(lpnW, lpConnA->lpPlayerName, sizeof(DPNAME));
  603. // Get Unicode copies of all the strings
  604. if(lpConnA->lpSessionDesc)
  605. {
  606. lpsdA = lpConnA->lpSessionDesc;
  607. if(lpsdA->lpszSessionNameA)
  608. {
  609. hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszSessionName),
  610. (LPSTR)lpsdA->lpszSessionNameA);
  611. if(FAILED(hr))
  612. {
  613. DPF_ERR("Unable to allocate temporary Unicode Session Name string");
  614. goto ERROR_CONVERT_DPLCONNECTION;
  615. }
  616. }
  617. if(lpsdA->lpszPasswordA)
  618. {
  619. hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszPassword),
  620. (LPSTR)lpsdA->lpszPasswordA);
  621. if(FAILED(hr))
  622. {
  623. DPF_ERR("Unable to allocate temporary Unicode Password string");
  624. goto ERROR_CONVERT_DPLCONNECTION;
  625. }
  626. }
  627. }
  628. if(lpConnA->lpPlayerName)
  629. {
  630. lpnA = lpConnA->lpPlayerName;
  631. if(lpnA->lpszShortNameA)
  632. {
  633. hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszShortName),
  634. (LPSTR)lpnA->lpszShortNameA);
  635. if(FAILED(hr))
  636. {
  637. DPF_ERR("Unable to allocate temporary Unicode Short Name string");
  638. goto ERROR_CONVERT_DPLCONNECTION;
  639. }
  640. }
  641. if(lpnA->lpszLongNameA)
  642. {
  643. hr = GetWideStringFromAnsi((LPWSTR *)&(lpwszLongName),
  644. (LPSTR)lpnA->lpszLongNameA);
  645. if(FAILED(hr))
  646. {
  647. DPF_ERR("Unable to allocate temporary Unicode Long Name string");
  648. goto ERROR_CONVERT_DPLCONNECTION;
  649. }
  650. }
  651. }
  652. // Now we've got everything so just fix up the pointers
  653. lpConnW->lpSessionDesc = lpsdW;
  654. lpConnW->lpPlayerName = lpnW;
  655. if(lpsdW)
  656. {
  657. lpsdW->lpszSessionName = lpwszSessionName;
  658. lpsdW->lpszPassword = lpwszPassword;
  659. }
  660. if(lpnW)
  661. {
  662. lpnW->lpszShortName = lpwszShortName;
  663. lpnW->lpszLongName = lpwszLongName;
  664. }
  665. *lplpConnW = lpConnW;
  666. return DP_OK;
  667. ERROR_CONVERT_DPLCONNECTION:
  668. if(lpConnW)
  669. DPMEM_FREE(lpConnW);
  670. if(lpsdW)
  671. DPMEM_FREE(lpsdW);
  672. if(lpnW)
  673. DPMEM_FREE(lpnW);
  674. if(lpwszSessionName)
  675. DPMEM_FREE(lpwszSessionName);
  676. if(lpwszPassword)
  677. DPMEM_FREE(lpwszPassword);
  678. if(lpwszShortName)
  679. DPMEM_FREE(lpwszShortName);
  680. if(lpwszLongName)
  681. DPMEM_FREE(lpwszLongName);
  682. return hr;
  683. } // PRV_ConvertDPLCONNECTIONToUnicode
  684. #undef DPF_MODNAME
  685. #define DPF_MODNAME "PRV_FixupDPLCONNECTIONPointers"
  686. void PRV_FixupDPLCONNECTIONPointers(LPDPLCONNECTION lpConn)
  687. {
  688. LPDPSESSIONDESC2 lpsd = NULL;
  689. LPDPNAME lpn = NULL;
  690. DPF(7, "Entering PRV_FixupDPLCONNECTIONPointers");
  691. DPF(9, "Parameters: 0x%08x", lpConn);
  692. // Make sure we have a valid DPLCONNECTION pointer
  693. if(!lpConn)
  694. {
  695. DPF_ERR("Invalid DPLCONNECTION pointer");
  696. ASSERT(FALSE);
  697. return;
  698. }
  699. // Fixup the DPSESSIONDESC2 pointer
  700. if(lpConn->lpSessionDesc)
  701. {
  702. lpsd = (LPDPSESSIONDESC2)((LPBYTE)lpConn + (DWORD_PTR)lpConn->lpSessionDesc);
  703. lpConn->lpSessionDesc = lpsd;
  704. }
  705. // Fixup the name strings in the SessionDesc struct
  706. if(lpsd)
  707. {
  708. // Fixup the session name
  709. if(lpsd->lpszSessionName)
  710. {
  711. lpsd->lpszSessionName = (LPWSTR)((LPBYTE)lpConn +
  712. (DWORD_PTR)lpsd->lpszSessionName);
  713. }
  714. // Fixup the password
  715. if(lpsd->lpszPassword)
  716. {
  717. lpsd->lpszPassword = (LPWSTR)((LPBYTE)lpConn +
  718. (DWORD_PTR)lpsd->lpszPassword);
  719. }
  720. }
  721. // Fixup the DPNAME pointer
  722. if(lpConn->lpPlayerName)
  723. {
  724. lpn = (LPDPNAME)((LPBYTE)lpConn + (DWORD_PTR)lpConn->lpPlayerName);
  725. lpConn->lpPlayerName = lpn;
  726. }
  727. // Fixup the name strings
  728. if(lpn)
  729. {
  730. // Fixup the short name
  731. if(lpn->lpszShortName)
  732. {
  733. lpn->lpszShortName = (LPWSTR)((LPBYTE)lpConn +
  734. (DWORD_PTR)lpn->lpszShortName);
  735. }
  736. // Fixup the long name
  737. if(lpn->lpszLongName)
  738. {
  739. lpn->lpszLongName = (LPWSTR)((LPBYTE)lpConn +
  740. (DWORD_PTR)lpn->lpszLongName);
  741. }
  742. }
  743. // Fixup the address pointer
  744. if(lpConn->lpAddress)
  745. {
  746. lpConn->lpAddress = (LPBYTE)lpConn + (DWORD_PTR)lpConn->lpAddress;
  747. }
  748. } // PRV_FixupDPLCONNECTIONPointers
  749. #undef DPF_MODNAME
  750. #define DPF_MODNAME "PRV_ConvertDPLCONNECTIONToAnsiInPlace"
  751. HRESULT PRV_ConvertDPLCONNECTIONToAnsiInPlace(LPDPLCONNECTION lpConn,
  752. LPDWORD lpdwSize, DWORD dwHeaderSize)
  753. {
  754. DWORD dwSessionNameSize = 0, dwPasswordSize = 0;
  755. DWORD dwShortNameSize = 0, dwLongNameSize = 0;
  756. DWORD dwSessionDescSize = 0, dwNameSize = 0;
  757. DWORD dwAnsiSize = 0;
  758. LPSTR lpszSession = NULL, lpszPassword = 0;
  759. LPSTR lpszShort = NULL, lpszLong = 0;
  760. LPBYTE lpByte = NULL;
  761. DPF(7, "Entering PRV_ConvertDPLCONNECTIONToAnsiInPlace");
  762. DPF(9, "Parameters: 0x%08x, 0x%08x, %lu",
  763. lpConn, lpdwSize, dwHeaderSize);
  764. // If we don't have a DPLCONNECTION struct, something's wrong
  765. ASSERT(lpConn);
  766. ASSERT(lpdwSize);
  767. // Start with the DPSESSIONDESC2 strings
  768. if(lpConn->lpSessionDesc)
  769. {
  770. if(lpConn->lpSessionDesc->lpszSessionName)
  771. {
  772. GetAnsiString(&lpszSession, lpConn->lpSessionDesc->lpszSessionName);
  773. dwSessionNameSize = STRLEN(lpszSession);
  774. }
  775. if(lpConn->lpSessionDesc->lpszPassword)
  776. {
  777. GetAnsiString(&lpszPassword, lpConn->lpSessionDesc->lpszPassword);
  778. dwPasswordSize = STRLEN(lpszPassword);
  779. }
  780. dwSessionDescSize = sizeof(DPSESSIONDESC2) + dwSessionNameSize +
  781. dwPasswordSize;
  782. }
  783. // Next the DPNAME strings
  784. if(lpConn->lpPlayerName)
  785. {
  786. if(lpConn->lpPlayerName->lpszShortName)
  787. {
  788. GetAnsiString(&lpszShort, lpConn->lpPlayerName->lpszShortName);
  789. dwShortNameSize = STRLEN(lpszShort);
  790. }
  791. if(lpConn->lpPlayerName->lpszLongName)
  792. {
  793. GetAnsiString(&lpszLong, lpConn->lpPlayerName->lpszLongName);
  794. dwLongNameSize = STRLEN(lpszLong);
  795. }
  796. dwNameSize = sizeof(DPNAME) + dwShortNameSize + dwLongNameSize;
  797. }
  798. dwAnsiSize = dwHeaderSize + sizeof(DPLCONNECTION) +
  799. dwSessionDescSize + dwNameSize + lpConn->dwAddressSize;
  800. if (dwAnsiSize > *lpdwSize)
  801. {
  802. if(lpszSession)
  803. DPMEM_FREE(lpszSession);
  804. if(lpszPassword)
  805. DPMEM_FREE(lpszPassword);
  806. if(lpszShort)
  807. DPMEM_FREE(lpszShort);
  808. if(lpszLong)
  809. DPMEM_FREE(lpszLong);
  810. *lpdwSize = dwAnsiSize;
  811. return DPERR_BUFFERTOOSMALL;
  812. }
  813. // store return size
  814. *lpdwSize = dwAnsiSize;
  815. // figure out where to start repacking strings
  816. lpByte = (LPBYTE)lpConn + sizeof(DPLCONNECTION);
  817. if(lpConn->lpSessionDesc)
  818. lpByte += sizeof(DPSESSIONDESC2);
  819. if(lpConn->lpPlayerName)
  820. lpByte += sizeof(DPNAME);
  821. // repack 'em
  822. if(lpszSession)
  823. {
  824. memcpy(lpByte, lpszSession, dwSessionNameSize);
  825. lpConn->lpSessionDesc->lpszSessionNameA = (LPSTR)lpByte;
  826. DPMEM_FREE(lpszSession);
  827. lpByte += dwSessionNameSize;
  828. }
  829. if(lpszPassword)
  830. {
  831. memcpy(lpByte, lpszPassword, dwPasswordSize);
  832. lpConn->lpSessionDesc->lpszPasswordA = (LPSTR)lpByte;
  833. DPMEM_FREE(lpszPassword);
  834. lpByte += dwPasswordSize;
  835. }
  836. if(lpszShort)
  837. {
  838. memcpy(lpByte, lpszShort, dwShortNameSize);
  839. lpConn->lpPlayerName->lpszShortNameA = (LPSTR)lpByte;
  840. DPMEM_FREE(lpszShort);
  841. lpByte += dwShortNameSize;
  842. }
  843. if(lpszLong)
  844. {
  845. memcpy(lpByte, lpszLong, dwLongNameSize);
  846. lpConn->lpPlayerName->lpszLongNameA = (LPSTR)lpByte;
  847. DPMEM_FREE(lpszLong);
  848. lpByte += dwLongNameSize;
  849. }
  850. if(lpConn->lpAddress)
  851. {
  852. // recopy the address, and account for the fact that we could
  853. // be doing an overlapping memory copy (So use MoveMemory instead
  854. // of CopyMemory or memcpy)
  855. MoveMemory(lpByte, lpConn->lpAddress, lpConn->dwAddressSize);
  856. lpConn->lpAddress = lpByte;
  857. }
  858. return DP_OK;
  859. } // PRV_ConvertDPLCONNECTIONToAnsiInPlace
  860. #undef DPF_MODNAME
  861. #define DPF_MODNAME "PRV_ValidateDPAPPLICATIONDESC"
  862. HRESULT PRV_ValidateDPAPPLICATIONDESC(LPDPAPPLICATIONDESC lpDesc, BOOL bAnsi)
  863. {
  864. DWORD LobbyDescVer;
  865. LPDPAPPLICATIONDESC2 lpDesc2=(LPDPAPPLICATIONDESC2) lpDesc;
  866. DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
  867. DPF(9, "Parameters: 0x%08x, %lu", lpDesc, bAnsi);
  868. TRY
  869. {
  870. // Validate the connection structure itself
  871. if(VALID_DPLOBBY_APPLICATIONDESC(lpDesc)){
  872. LobbyDescVer=1;
  873. } else if (VALID_DPLOBBY_APPLICATIONDESC2(lpDesc)){
  874. LobbyDescVer=2;
  875. } else {
  876. DPF_ERR("Invalid structure pointer or invalid size");
  877. return DPERR_INVALIDPARAMS;
  878. }
  879. // Validate the flags
  880. if(!VALID_REGISTERAPP_FLAGS(lpDesc->dwFlags))
  881. {
  882. DPF_ERR("Invalid flags exist in the dwFlags member of the DPAPPLICATIONDESC structure");
  883. return DPERR_INVALIDFLAGS;
  884. }
  885. if((lpDesc->dwFlags & (DPLAPP_AUTOVOICE|DPLAPP_SELFVOICE))==(DPLAPP_AUTOVOICE|DPLAPP_SELFVOICE))
  886. {
  887. return DPERR_INVALIDFLAGS;
  888. }
  889. // Validate the ApplicationName string (required)
  890. if(lpDesc->lpszApplicationName)
  891. {
  892. if(!VALID_READ_PTR(lpDesc->lpszApplicationName, (bAnsi ?
  893. strlen(lpDesc->lpszApplicationNameA) :
  894. WSTRLEN_BYTES(lpDesc->lpszApplicationName))))
  895. {
  896. DPF_ERR("Invalid lpszApplicationName string in DPAPPLICTIONDESC structure");
  897. return DPERR_INVALIDPARAMS;
  898. }
  899. }
  900. else
  901. {
  902. DPF_ERR("The lpszApplicationName member of the DPAPPLICTIONDESC structure is required");
  903. return DPERR_INVALIDPARAMS;
  904. }
  905. // Validate the GUID (required)
  906. // We can really only check this against GUID_NULL since it will
  907. // always be a valid guid structure inside the APPDESC struct
  908. if(IsEqualGUID(&lpDesc->guidApplication, &GUID_NULL))
  909. {
  910. DPF_ERR("The guidApplication member of the DPAPPLICTIONDESC structure is required");
  911. return DPERR_INVALIDPARAMS;
  912. }
  913. // Validate the Filename string (required)
  914. if(lpDesc->lpszFilename)
  915. {
  916. if(!VALID_READ_PTR(lpDesc->lpszFilename, (bAnsi ?
  917. strlen(lpDesc->lpszFilenameA) :
  918. WSTRLEN_BYTES(lpDesc->lpszFilename))))
  919. {
  920. DPF_ERR("Invalid lpszFilename string in DPAPPLICTIONDESC structure");
  921. return DPERR_INVALIDPARAMS;
  922. }
  923. }
  924. else
  925. {
  926. DPF_ERR("The lpszFilename member of the DPAPPLICTIONDESC structure is required");
  927. return DPERR_INVALIDPARAMS;
  928. }
  929. // Validate the CommandLine string (optional)
  930. if(lpDesc->lpszCommandLine)
  931. {
  932. if(!VALID_READ_PTR(lpDesc->lpszCommandLine, (bAnsi ?
  933. strlen(lpDesc->lpszCommandLineA) :
  934. WSTRLEN_BYTES(lpDesc->lpszCommandLine))))
  935. {
  936. DPF_ERR("Invalid lpszCommandLine string in DPAPPLICTIONDESC structure");
  937. return DPERR_INVALIDPARAMS;
  938. }
  939. }
  940. // Validate the Path string (required)
  941. if(lpDesc->lpszPath)
  942. {
  943. if(!VALID_READ_PTR(lpDesc->lpszPath, (bAnsi ?
  944. strlen(lpDesc->lpszPathA) :
  945. WSTRLEN_BYTES(lpDesc->lpszPath))))
  946. {
  947. DPF_ERR("Invalid lpszPath string in DPAPPLICTIONDESC structure");
  948. return DPERR_INVALIDPARAMS;
  949. }
  950. }
  951. else
  952. {
  953. DPF_ERR("The lpszPath member of the DPAPPLICTIONDESC structure is required");
  954. return DPERR_INVALIDPARAMS;
  955. }
  956. // Validate the CurrentDirectory string (optional)
  957. if(lpDesc->lpszCurrentDirectory)
  958. {
  959. if(!VALID_READ_PTR(lpDesc->lpszCurrentDirectory, (bAnsi ?
  960. strlen(lpDesc->lpszCurrentDirectoryA) :
  961. WSTRLEN_BYTES(lpDesc->lpszCurrentDirectory))))
  962. {
  963. DPF_ERR("Invalid lpszCurrentDirectory string in DPAPPLICTIONDESC structure");
  964. return DPERR_INVALIDPARAMS;
  965. }
  966. }
  967. // Validate the DescriptionA string (optional)
  968. if(lpDesc->lpszDescriptionA)
  969. {
  970. if(!VALID_READ_PTR(lpDesc->lpszDescriptionA,
  971. strlen(lpDesc->lpszDescriptionA)))
  972. {
  973. DPF_ERR("Invalid lpszDescriptionA string in DPAPPLICTIONDESC structure");
  974. return DPERR_INVALIDPARAMS;
  975. }
  976. }
  977. // Validate the DescriptionW string (optional)
  978. if(lpDesc->lpszDescriptionW)
  979. {
  980. if(!VALID_READ_PTR(lpDesc->lpszDescriptionW,
  981. WSTRLEN_BYTES(lpDesc->lpszDescriptionW)))
  982. {
  983. DPF_ERR("Invalid lpszDescriptionW string in DPAPPLICTIONDESC structure");
  984. return DPERR_INVALIDPARAMS;
  985. }
  986. }
  987. // if the DPAPPLICATIONDESC2 is being used, validate the launcher name if present
  988. if(LobbyDescVer==2)
  989. {
  990. // Validate AppLauncherName Name
  991. if(lpDesc2->lpszAppLauncherNameA){
  992. if(!VALID_READ_PTR(lpDesc2->lpszAppLauncherNameA, (bAnsi ?
  993. strlen(lpDesc2->lpszAppLauncherNameA) :
  994. WSTRLEN_BYTES(lpDesc2->lpszAppLauncherName))))
  995. {
  996. DPF_ERR("Invalid lpszAppLauncherName string in DPAPPLICATIONDESC2 structure");
  997. return DPERR_INVALIDPARAMS;
  998. }
  999. }
  1000. }
  1001. }
  1002. EXCEPT( EXCEPTION_EXECUTE_HANDLER )
  1003. {
  1004. DPF_ERR( "Exception encountered validating parameters" );
  1005. return DPERR_INVALIDPARAMS;
  1006. }
  1007. return DP_OK;
  1008. } // PRV_ValidateDPAPPLICATIONDESC
  1009. #undef DPF_MODNAME
  1010. #define DPF_MODNAME "PRV_ConvertDPAPPLICATIONDESCToUnicode"
  1011. HRESULT PRV_ConvertDPAPPLICATIONDESCToUnicode(LPDPAPPLICATIONDESC lpDescA,
  1012. LPDPAPPLICATIONDESC * lplpDescW)
  1013. {
  1014. #define lpDesc2A ((LPDPAPPLICATIONDESC2) lpDescA)
  1015. #define lpDesc2W ((LPDPAPPLICATIONDESC2) lpDescW)
  1016. LPDPAPPLICATIONDESC lpDescW = NULL;
  1017. LPWSTR lpwszApplicationName = NULL;
  1018. LPWSTR lpwszFilename = NULL;
  1019. LPWSTR lpwszCommandLine = NULL;
  1020. LPWSTR lpwszPath = NULL;
  1021. LPWSTR lpwszCurrentDirectory = NULL;
  1022. LPWSTR lpwszAppLauncherName = NULL;
  1023. HRESULT hr;
  1024. DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
  1025. DPF(9, "Parameters: 0x%08x, 0x%08x", lpDescA, lplpDescW);
  1026. ASSERT(lpDescA);
  1027. ASSERT(lplpDescW);
  1028. // Allocate memory for the DPAPPLICATIONDESC structure
  1029. lpDescW = DPMEM_ALLOC(lpDescA->dwSize);
  1030. if(!lpDescW)
  1031. {
  1032. DPF_ERR("Unable to allocate memory for temporary Unicode DPAPPLICATIONDESC struct");
  1033. hr = DPERR_OUTOFMEMORY;
  1034. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1035. }
  1036. // Copy the structure itself
  1037. memcpy(lpDescW, lpDescA, lpDescA->dwSize);
  1038. // Convert the ApplicationName
  1039. if(lpDescA->lpszApplicationNameA)
  1040. {
  1041. hr = GetWideStringFromAnsi(&lpwszApplicationName,
  1042. lpDescA->lpszApplicationNameA);
  1043. if(FAILED(hr))
  1044. {
  1045. DPF_ERR("Unable to convert ApplicationName string to Unicode");
  1046. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1047. }
  1048. }
  1049. // Convert the Filename
  1050. if(lpDescA->lpszFilenameA)
  1051. {
  1052. hr = GetWideStringFromAnsi(&lpwszFilename,
  1053. lpDescA->lpszFilenameA);
  1054. if(FAILED(hr))
  1055. {
  1056. DPF_ERR("Unable to convert Filename string to Unicode");
  1057. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1058. }
  1059. }
  1060. // Convert the CommandLine
  1061. if(lpDescA->lpszCommandLineA)
  1062. {
  1063. hr = GetWideStringFromAnsi(&lpwszCommandLine,
  1064. lpDescA->lpszCommandLineA);
  1065. if(FAILED(hr))
  1066. {
  1067. DPF_ERR("Unable to convert CommandLine string to Unicode");
  1068. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1069. }
  1070. }
  1071. // Convert the Path
  1072. if(lpDescA->lpszPathA)
  1073. {
  1074. hr = GetWideStringFromAnsi(&lpwszPath,
  1075. lpDescA->lpszPathA);
  1076. if(FAILED(hr))
  1077. {
  1078. DPF_ERR("Unable to convert Path string to Unicode");
  1079. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1080. }
  1081. }
  1082. // Convert the CurrentDirectory
  1083. if(lpDescA->lpszCurrentDirectoryA)
  1084. {
  1085. hr = GetWideStringFromAnsi(&lpwszCurrentDirectory,
  1086. lpDescA->lpszCurrentDirectoryA);
  1087. if(FAILED(hr))
  1088. {
  1089. DPF_ERR("Unable to convert CurrentDirectory string to Unicode");
  1090. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1091. }
  1092. }
  1093. // Convert the AppLauncher string if presend on an APPLICATIONDESC2
  1094. if(IS_DPLOBBY_APPLICATIONDESC2(lpDescA)){
  1095. if(lpDesc2A->lpszAppLauncherNameA){
  1096. hr = GetWideStringFromAnsi(&lpwszAppLauncherName,
  1097. lpDesc2A->lpszAppLauncherNameA);
  1098. if(FAILED(hr))
  1099. {
  1100. DPF_ERR("Unable to convert CurrentDirectory string to Unicode");
  1101. goto ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE;
  1102. }
  1103. }
  1104. lpDesc2W->lpszAppLauncherName=lpwszAppLauncherName;
  1105. }
  1106. // We won't convert the description strings because they will
  1107. // get put in the registry as-is.
  1108. // So now that we have all the strings, setup the structure
  1109. lpDescW->lpszApplicationName = lpwszApplicationName;
  1110. lpDescW->lpszFilename = lpwszFilename;
  1111. lpDescW->lpszCommandLine = lpwszCommandLine;
  1112. lpDescW->lpszPath = lpwszPath;
  1113. lpDescW->lpszCurrentDirectory = lpwszCurrentDirectory;
  1114. lpDescW->lpszDescriptionA = lpDescA->lpszDescriptionA;
  1115. lpDescW->lpszDescriptionW = lpDescA->lpszDescriptionW;
  1116. // Set the output pointer
  1117. *lplpDescW = lpDescW;
  1118. return DP_OK;
  1119. ERROR_CONVERT_DPAPPLICATIONDESC_UNICODE:
  1120. if(lpwszApplicationName)
  1121. DPMEM_FREE(lpwszApplicationName);
  1122. if(lpwszFilename)
  1123. DPMEM_FREE(lpwszFilename);
  1124. if(lpwszCommandLine)
  1125. DPMEM_FREE(lpwszCommandLine);
  1126. if(lpwszPath)
  1127. DPMEM_FREE(lpwszPath);
  1128. if(lpwszCurrentDirectory)
  1129. DPMEM_FREE(lpwszCurrentDirectory);
  1130. if(lpDescW)
  1131. DPMEM_FREE(lpDescW);
  1132. if(lpwszAppLauncherName){
  1133. DPMEM_FREE(lpwszAppLauncherName);
  1134. }
  1135. return hr;
  1136. #undef lpDesc2A
  1137. #undef lpDesc2W
  1138. } // PRV_ConvertDPAPPLICATIONDESCToUnicode
  1139. #undef DPF_MODNAME
  1140. #define DPF_MODNAME "PRV_ConvertDPAPPLICATIONDESCToAnsi"
  1141. HRESULT PRV_ConvertDPAPPLICATIONDESCToAnsi(LPDPAPPLICATIONDESC lpDescW,
  1142. LPDPAPPLICATIONDESC * lplpDescA)
  1143. {
  1144. #define lpDesc2W ((LPDPAPPLICATIONDESC2)(lpDescW))
  1145. #define lpDesc2A ((LPDPAPPLICATIONDESC2)(lpDescA))
  1146. LPDPAPPLICATIONDESC lpDescA = NULL;
  1147. LPSTR lpszApplicationName = NULL;
  1148. LPSTR lpszFilename = NULL;
  1149. LPSTR lpszCommandLine = NULL;
  1150. LPSTR lpszPath = NULL;
  1151. LPSTR lpszCurrentDirectory = NULL;
  1152. LPSTR lpszAppLauncherName=NULL;
  1153. HRESULT hr;
  1154. DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
  1155. DPF(9, "Parameters: 0x%08x, 0x%08x", lpDescW, lplpDescA);
  1156. ASSERT(lpDescW);
  1157. ASSERT(lplpDescA);
  1158. // Allocate memory for the DPAPPLICATIONDESC structure
  1159. lpDescA = DPMEM_ALLOC(lpDescW->dwSize);
  1160. if(!lpDescA)
  1161. {
  1162. DPF_ERR("Unable to allocate memory for temporary Ansi DPAPPLICATIONDESC struct");
  1163. hr = DPERR_OUTOFMEMORY;
  1164. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1165. }
  1166. // Copy the structure itself
  1167. memcpy(lpDescA, lpDescW, lpDescW->dwSize);
  1168. // Convert the ApplicationName
  1169. if(lpDescW->lpszApplicationName)
  1170. {
  1171. hr = GetAnsiString(&lpszApplicationName, lpDescW->lpszApplicationName);
  1172. if(FAILED(hr))
  1173. {
  1174. DPF_ERR("Unable to convert ApplicationName string to Ansi");
  1175. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1176. }
  1177. }
  1178. // Convert the Filename
  1179. if(lpDescW->lpszFilename)
  1180. {
  1181. hr = GetAnsiString(&lpszFilename, lpDescW->lpszFilename);
  1182. if(FAILED(hr))
  1183. {
  1184. DPF_ERR("Unable to convert Filename string to Ansi");
  1185. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1186. }
  1187. }
  1188. // Convert the CommandLine
  1189. if(lpDescW->lpszCommandLine)
  1190. {
  1191. hr = GetAnsiString(&lpszCommandLine, lpDescW->lpszCommandLine);
  1192. if(FAILED(hr))
  1193. {
  1194. DPF_ERR("Unable to convert CommandLine string to Ansi");
  1195. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1196. }
  1197. }
  1198. // Convert the Path
  1199. if(lpDescW->lpszPath)
  1200. {
  1201. hr = GetAnsiString(&lpszPath, lpDescW->lpszPath);
  1202. if(FAILED(hr))
  1203. {
  1204. DPF_ERR("Unable to convert Path string to Ansi");
  1205. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1206. }
  1207. }
  1208. // Convert the CurrentDirectory
  1209. if(lpDescW->lpszCurrentDirectory)
  1210. {
  1211. hr = GetAnsiString(&lpszCurrentDirectory, lpDescW->lpszCurrentDirectory);
  1212. if(FAILED(hr))
  1213. {
  1214. DPF_ERR("Unable to convert CurrentDirectory string to Ansi");
  1215. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1216. }
  1217. }
  1218. // Convers the app launcher string if present.
  1219. if(IS_DPLOBBY_APPLICATIONDESC2(lpDesc2W)){
  1220. if(lpDesc2W->lpszAppLauncherName){
  1221. hr = GetAnsiString(&lpszAppLauncherName, lpDesc2W->lpszAppLauncherName);
  1222. if(FAILED(hr))
  1223. {
  1224. DPF_ERR("Unable to convert AppLauncherName string to Ansi");
  1225. goto ERROR_CONVERT_DPAPPLICATIONDESC_ANSI;
  1226. }
  1227. }
  1228. lpDesc2A->lpszAppLauncherNameA = lpszAppLauncherName;
  1229. }
  1230. // We won't convert the description strings because they will
  1231. // get put in the registry as-is.
  1232. // So now that we have all the strings, setup the structure
  1233. lpDescA->lpszApplicationNameA = lpszApplicationName;
  1234. lpDescA->lpszFilenameA = lpszFilename;
  1235. lpDescA->lpszCommandLineA = lpszCommandLine;
  1236. lpDescA->lpszPathA = lpszPath;
  1237. lpDescA->lpszCurrentDirectoryA = lpszCurrentDirectory;
  1238. lpDescA->lpszDescriptionA = lpDescW->lpszDescriptionA;
  1239. lpDescA->lpszDescriptionW = lpDescW->lpszDescriptionW;
  1240. // Set the output pointer
  1241. *lplpDescA = lpDescA;
  1242. return DP_OK;
  1243. ERROR_CONVERT_DPAPPLICATIONDESC_ANSI:
  1244. if(lpszApplicationName)
  1245. DPMEM_FREE(lpszApplicationName);
  1246. if(lpszFilename)
  1247. DPMEM_FREE(lpszFilename);
  1248. if(lpszCommandLine)
  1249. DPMEM_FREE(lpszCommandLine);
  1250. if(lpszPath)
  1251. DPMEM_FREE(lpszPath);
  1252. if(lpszCurrentDirectory)
  1253. DPMEM_FREE(lpszCurrentDirectory);
  1254. if(lpDescA)
  1255. DPMEM_FREE(lpDescA);
  1256. if(lpszAppLauncherName)
  1257. DPMEM_FREE(lpszAppLauncherName);
  1258. return hr;
  1259. #undef lpDesc2A
  1260. #undef lpDesc2W
  1261. } // PRV_ConvertDPAPPLICATIONDESCToAnsi
  1262. #undef DPF_MODNAME
  1263. #define DPF_MODNAME "PRV_FreeLocalDPAPPLICATIONDESC"
  1264. void PRV_FreeLocalDPAPPLICATIONDESC(LPDPAPPLICATIONDESC lpDesc)
  1265. {
  1266. LPDPAPPLICATIONDESC2 lpDesc2 = (LPDPAPPLICATIONDESC2)lpDesc;
  1267. DPF(7, "Entering PRV_ValidateDPAPPLICATIONDESC");
  1268. DPF(9, "Parameters: 0x%08x", lpDesc);
  1269. if(lpDesc)
  1270. {
  1271. if(lpDesc->lpszApplicationName)
  1272. DPMEM_FREE(lpDesc->lpszApplicationName);
  1273. if(lpDesc->lpszFilename)
  1274. DPMEM_FREE(lpDesc->lpszFilename);
  1275. if(lpDesc->lpszCommandLine)
  1276. DPMEM_FREE(lpDesc->lpszCommandLine);
  1277. if(lpDesc->lpszPath)
  1278. DPMEM_FREE(lpDesc->lpszPath);
  1279. if(lpDesc->lpszCurrentDirectory)
  1280. DPMEM_FREE(lpDesc->lpszCurrentDirectory);
  1281. if(IS_DPLOBBY_APPLICATIONDESC2(lpDesc) && lpDesc2->lpszAppLauncherName)
  1282. DPMEM_FREE(lpDesc2->lpszAppLauncherName);
  1283. // Note: We don't need to free the Description strings because they
  1284. // were never allocated in either of the above routines, the pointers
  1285. // were just copied.
  1286. DPMEM_FREE(lpDesc);
  1287. }
  1288. } // PRV_FreeLocalDPAPPLICATIONDESC