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.

450 lines
14 KiB

  1. #ifndef WIN32_LEAN_AND_MEAN
  2. #define WIN32_LEAN_AND_MEAN
  3. #endif
  4. #include <windows.h>
  5. #include "MarshalPC.h"
  6. #include <string.h>
  7. //*****************************************************************************
  8. // Un/Marshaling
  9. //*****************************************************************************
  10. void InitXSCM(LPMYSCARDHANDLE phTmp, const BYTE *pbBuffer, WORD len)
  11. {
  12. phTmp->xSCM.wResLen = len;
  13. if (FLAG2VERSION(phTmp->dwFlags) == VERSION_1_0)
  14. phTmp->xSCM.wExpLen = 1; // Prereserves the return code
  15. else
  16. phTmp->xSCM.wExpLen = 0; // Return code in SW2
  17. phTmp->xSCM.wGenLen = 0;
  18. phTmp->xSCM.pbBuffer = (LPBYTE)pbBuffer;
  19. }
  20. WORD GetSCMBufferLength(LPXSCM pxSCM)
  21. {
  22. return pxSCM->wGenLen;
  23. }
  24. BYTE *GetSCMCrtPointer(LPXSCM pxSCM)
  25. {
  26. return pxSCM->pbBuffer;
  27. }
  28. //*****************************************************************************
  29. // PARAM EXTRACTION (we care only that there is enough data received, i.e.
  30. // we ignore pxSCM->wGenLen & pxSCM->wExpLen
  31. SCODE XSCM2SCODE(LPXSCM pxSCM)
  32. {
  33. BYTE by;
  34. if (pxSCM->wResLen == 0)
  35. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  36. pxSCM->wResLen -= sizeof(UINT8);
  37. by = *(pxSCM->pbBuffer)++;
  38. return MAKESCODE(by);
  39. }
  40. UINT8 XSCM2UINT8(LPXSCM pxSCM)
  41. {
  42. if (pxSCM->wResLen == 0)
  43. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  44. pxSCM->wResLen -= sizeof(UINT8);
  45. return *((UINT8 *)pxSCM->pbBuffer)++;
  46. }
  47. HFILE XSCM2HFILE(LPXSCM pxSCM)
  48. {
  49. return (HFILE)(XSCM2UINT8(pxSCM));
  50. }
  51. UINT16 XSCM2UINT16(LPXSCM pxSCM, BOOL fBigEndian)
  52. {
  53. if (pxSCM->wResLen < sizeof(UINT16))
  54. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  55. pxSCM->wResLen -= sizeof(UINT16);
  56. if (fBigEndian)
  57. {
  58. UINT16 w = *((UINT16 *)pxSCM->pbBuffer)++;
  59. w = (UINT16)(w>>8) | (UINT16)(w<<8);
  60. return w;
  61. }
  62. else
  63. return *((UNALIGNED UINT16 *)pxSCM->pbBuffer)++;
  64. }
  65. // Returns length in WCHAR
  66. WCSTR XSCM2String(LPXSCM pxSCM, UINT8 *plen, BOOL fBigEndian)
  67. {
  68. // Get the length (addr next byte + length -> next object
  69. WCSTR wsz;
  70. UINT8 len, i;
  71. len = XSCM2UINT8(pxSCM);
  72. if (len == 0)
  73. {
  74. wsz = NULL;
  75. }
  76. else
  77. {
  78. if (pxSCM->wResLen < (WORD)len)
  79. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  80. pxSCM->wResLen -= (WORD)len;
  81. wsz = (WCSTR)pxSCM->pbBuffer;
  82. // In place byte switching
  83. // if (fBigEndian)
  84. // {
  85. // BYTE b;
  86. // for (i=0 ; i<(len&0xF7)-2 ; i+=2)
  87. // {
  88. // b = pxSCM->pbBuffer[i];
  89. // pxSCM->pbBuffer[i] = pxSCM->pbBuffer[i + 1];
  90. // pxSCM->pbBuffer[i+1] = b;
  91. // }
  92. // }
  93. // Verify 0 terminated within len/2
  94. for (i=0 ; i<len/2 ; i++)
  95. {
  96. if (wsz[i] == (WCHAR)0)
  97. break;
  98. }
  99. if (i >= len/2)
  100. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  101. else
  102. len = i+1;
  103. pxSCM->pbBuffer += len;
  104. }
  105. if (plen)
  106. *plen = len;
  107. return wsz;
  108. }
  109. TCOUNT XSCM2ByteArray(LPXSCM pxSCM, UINT8 **ppb)
  110. {
  111. TCOUNT len = XSCM2UINT8(pxSCM);
  112. if (len)
  113. {
  114. if (pxSCM->wResLen < (WORD)len)
  115. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  116. pxSCM->wResLen -= (WORD)len;
  117. *ppb = (UINT8 *)pxSCM->pbBuffer;
  118. pxSCM->pbBuffer += len;
  119. }
  120. else
  121. *ppb = NULL;
  122. return len;
  123. }
  124. //*****************************************************************************
  125. void UINT82XSCM(LPXSCM pxSCM, UINT8 val, int type)
  126. {
  127. switch (type)
  128. {
  129. case TYPE_NOTYPE_NOCOUNT: // Goes in the header
  130. break; // There can't be a problem
  131. case TYPE_NOTYPE_COUNT: // Probably #param or a param type (1 byte)
  132. if (pxSCM->wExpLen + sizeof(UINT8) > pxSCM->wResLen)
  133. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  134. break;
  135. case TYPE_TYPED: // 8 bits number passed by value (2 bytes)
  136. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
  137. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  138. // Prefix by the type (8)
  139. *((UINT8 *)pxSCM->pbBuffer)++ = 8;
  140. pxSCM->wExpLen += sizeof(UINT8);
  141. pxSCM->wGenLen += sizeof(UINT8);
  142. break;
  143. }
  144. // Add the value already !
  145. *((UINT8 *)pxSCM->pbBuffer)++ = val;
  146. if (type != TYPE_NOTYPE_NOCOUNT) // Header doesn't count as expanded
  147. pxSCM->wExpLen += sizeof(UINT8);
  148. pxSCM->wGenLen += sizeof(UINT8);
  149. }
  150. // proxies HFILE as an UINT8
  151. void HFILE2XSCM(LPXSCM pxSCM, HFILE val)
  152. {
  153. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
  154. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  155. // Prefix by the type (8 -> UINT8)
  156. *((UINT8 *)pxSCM->pbBuffer)++ = 8;
  157. pxSCM->wExpLen += sizeof(UINT8);
  158. pxSCM->wGenLen += sizeof(UINT8);
  159. *((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)val;
  160. pxSCM->wExpLen += sizeof(UINT8);
  161. pxSCM->wGenLen += sizeof(UINT8);
  162. }
  163. void UINT162XSCM(LPXSCM pxSCM, UINT16 val, BOOL fBigEndian)
  164. {
  165. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT16) > pxSCM->wResLen)
  166. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  167. // Prefix by the type (16)
  168. *((UINT8 *)pxSCM->pbBuffer)++ = 16;
  169. pxSCM->wExpLen += sizeof(UINT8);
  170. pxSCM->wGenLen += sizeof(UINT8);
  171. if (fBigEndian)
  172. {
  173. *pxSCM->pbBuffer++ = (BYTE)(val>>8);
  174. *pxSCM->pbBuffer++ = (BYTE)(val);
  175. }
  176. else
  177. *((UNALIGNED UINT16 *)pxSCM->pbBuffer)++ = val;
  178. pxSCM->wExpLen += sizeof(UINT16);
  179. pxSCM->wGenLen += sizeof(UINT16);
  180. }
  181. void ByteArray2XSCM(LPXSCM pxSCM, const BYTE *pbBuffer, TCOUNT len)
  182. {
  183. if (pbBuffer == NULL)
  184. {
  185. // This is equivalent to marshal a NULL & "len as a UINT8"
  186. NULL2XSCM(pxSCM);
  187. UINT82XSCM(pxSCM, len, TYPE_TYPED);
  188. }
  189. else
  190. {
  191. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
  192. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  193. // Prefix by the type ('A')
  194. *((UINT8 *)pxSCM->pbBuffer)++ = 'A';
  195. pxSCM->wExpLen += sizeof(UINT8);
  196. pxSCM->wGenLen += sizeof(UINT8);
  197. // Add the length
  198. *((UINT8 *)pxSCM->pbBuffer)++ = len;
  199. pxSCM->wExpLen += sizeof(UINT8);
  200. pxSCM->wGenLen += sizeof(UINT8);
  201. // Add the data already
  202. memcpy(pxSCM->pbBuffer, pbBuffer, len);
  203. pxSCM->pbBuffer += len;
  204. pxSCM->wExpLen += len;
  205. pxSCM->wGenLen += len;
  206. }
  207. }
  208. void String2XSCM(LPXSCM pxSCM, WCSTR wsz, BOOL fBigEndian)
  209. {
  210. UINT16 len; //, i;
  211. if (wsz == NULL)
  212. {
  213. // This is equivalent to marshal a NULL
  214. NULL2XSCM(pxSCM);
  215. }
  216. else
  217. {
  218. // No overflow needs to be checked in the following assignement to len
  219. if (wcslen(wsz) > 0x7FFE)
  220. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  221. // compute the length (addr next byte + length -> next object
  222. len = (wcslen(wsz) + 1) * sizeof(WCHAR);
  223. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
  224. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  225. // Prefix by the type ('S')
  226. *((UINT8 *)pxSCM->pbBuffer)++ = 'S';
  227. pxSCM->wExpLen += sizeof(UINT8);
  228. pxSCM->wGenLen += sizeof(UINT8);
  229. // Add the length
  230. *((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)len; // No chance the length check succeeds
  231. // if len > 255
  232. pxSCM->wExpLen += sizeof(UINT8);
  233. pxSCM->wGenLen += sizeof(UINT8);
  234. // Add the data already
  235. // Byte switching?
  236. // if (fBigEndian)
  237. // {
  238. // for (i=0 ; i<len ; i+=2)
  239. // {
  240. // pxSCM->pbBuffer[i] = (BYTE)(wsz[i>>1]>>8);
  241. // pxSCM->pbBuffer[i+1] = (BYTE)(wsz[i>>1]);
  242. // }
  243. // }
  244. // else
  245. memcpy(pxSCM->pbBuffer, (BYTE *)wsz, len);
  246. pxSCM->pbBuffer += len;
  247. pxSCM->wExpLen += len;
  248. pxSCM->wGenLen += len;
  249. }
  250. }
  251. void UINT8BYREF2XSCM(LPXSCM pxSCM, UINT8 *val)
  252. {
  253. if (val)
  254. {
  255. // In this case the card unmarshaling code will reserve 1 byte in the
  256. // OutputBuffer and have _param[_iparam++]._pv point to it
  257. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
  258. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  259. // Prefix by the type (108)
  260. *((UINT8 *)pxSCM->pbBuffer)++ = 108;
  261. pxSCM->wExpLen += sizeof(UINT8);
  262. pxSCM->wGenLen += sizeof(UINT8);
  263. // Add the value already
  264. *((UINT8 *)pxSCM->pbBuffer)++ = *val;
  265. pxSCM->wExpLen += sizeof(UINT8);
  266. pxSCM->wGenLen += sizeof(UINT8);
  267. // As mentioned above, 1 byte will be reserved in the output buffer
  268. pxSCM->wExpLen += sizeof(UINT8);
  269. }
  270. else
  271. {
  272. // This is equivalent to marshal a NULL
  273. NULL2XSCM(pxSCM);
  274. }
  275. }
  276. void HFILEBYREF2XSCM(LPXSCM pxSCM, HFILE *val)
  277. {
  278. if (val)
  279. {
  280. // In this case the card unmarshaling code will reserve 1 byte in the
  281. // OutputBuffer and have _param[_iparam++]._pv point to it
  282. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) > pxSCM->wResLen)
  283. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  284. // Prefix by the type (108)
  285. *((UINT8 *)pxSCM->pbBuffer)++ = 108;
  286. pxSCM->wExpLen += sizeof(UINT8);
  287. pxSCM->wGenLen += sizeof(UINT8);
  288. // Add the value already
  289. *((UINT8 *)pxSCM->pbBuffer)++ = (UINT8)*val;
  290. pxSCM->wExpLen += sizeof(UINT8);
  291. pxSCM->wGenLen += sizeof(UINT8);
  292. // As mentioned above, 1 byte will be reserved in the output buffer
  293. pxSCM->wExpLen += sizeof(UINT8);
  294. }
  295. else
  296. {
  297. // This is equivalent to marshal a NULL
  298. NULL2XSCM(pxSCM);
  299. }
  300. }
  301. void UINT16BYREF2XSCM(LPXSCM pxSCM, UINT16 *val, BOOL fBigEndian)
  302. {
  303. if (val)
  304. {
  305. // In this case the card unmarshaling code will reserve 2 bytes in the
  306. // OutputBuffer and have _param[_iparam++]._pv point to it
  307. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT16) + sizeof(UINT16) > pxSCM->wResLen)
  308. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  309. // Prefix by the type (116)
  310. *((UINT8 *)pxSCM->pbBuffer)++ = 116;
  311. pxSCM->wExpLen += sizeof(UINT8);
  312. pxSCM->wGenLen += sizeof(UINT8);
  313. // Add the value already
  314. if (fBigEndian)
  315. {
  316. *pxSCM->pbBuffer++ = (BYTE)((*val)>>8);
  317. *pxSCM->pbBuffer++ = (BYTE)(*val);
  318. }
  319. else
  320. *((UNALIGNED UINT16 *)pxSCM->pbBuffer)++ = *val;
  321. pxSCM->wExpLen += sizeof(UINT16);
  322. pxSCM->wGenLen += sizeof(UINT16);
  323. // As mentioned above, 2 bytes will be reserved in the output buffer
  324. pxSCM->wExpLen += sizeof(UINT16);
  325. }
  326. else
  327. {
  328. // This is equivalent to marshal a NULL
  329. NULL2XSCM(pxSCM);
  330. }
  331. }
  332. void ByteArrayOut2XSCM(LPXSCM pxSCM, BYTE *pb, TCOUNT len)
  333. {
  334. if (pb)
  335. {
  336. // In this case the card unmarshaling code will reserve 1+len bytes in the
  337. // OutputBuffer and have _param[_iparam++]._pv point to the len bytes
  338. // Note that the current buffer isn't passed in
  339. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) + len > pxSCM->wResLen)
  340. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  341. // Prefix by the type ('a')
  342. *((UINT8 *)pxSCM->pbBuffer)++ = 'a';
  343. pxSCM->wExpLen += sizeof(UINT8);
  344. pxSCM->wGenLen += sizeof(UINT8);
  345. // Add the length
  346. *((UINT8 *)pxSCM->pbBuffer)++ = len;
  347. pxSCM->wExpLen += sizeof(UINT8);
  348. pxSCM->wGenLen += sizeof(UINT8);
  349. // As mentioned above, 1+len bytes will be reserved in the output buffer
  350. pxSCM->wExpLen += sizeof(UINT8) + len;
  351. }
  352. else
  353. {
  354. // This is equivalent to marshal a NULL & "len as a UINT8"
  355. NULL2XSCM(pxSCM);
  356. UINT82XSCM(pxSCM, len, TYPE_TYPED);
  357. }
  358. }
  359. void StringOut2XSCM(LPXSCM pxSCM, WSTR wsz, TCOUNT len, BOOL fBigEndian)
  360. {
  361. if (wsz)
  362. {
  363. // len is a WCHAR count
  364. if (len > 127) // This would cause overflows in String marshaling
  365. RaiseException(STATUS_INVALID_PARAM, 0, 0, 0);
  366. // In this case the card unmarshaling code will reserve 1+len*2 bytes in the
  367. // OutputBuffer and have _param[_iparam++]._pv point to the len bytes
  368. // Note that the current buffer isn't passed in
  369. if (pxSCM->wExpLen + sizeof(UINT8) + sizeof(UINT8) + sizeof(UINT8) + len*2 > pxSCM->wResLen)
  370. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  371. // Prefix by the type ('s')
  372. *((UINT8 *)pxSCM->pbBuffer)++ = 's';
  373. pxSCM->wExpLen += sizeof(UINT8);
  374. pxSCM->wGenLen += sizeof(UINT8);
  375. *((UINT8 *)pxSCM->pbBuffer)++ = len*2;
  376. pxSCM->wExpLen += sizeof(UINT8);
  377. pxSCM->wGenLen += sizeof(UINT8);
  378. // As mentioned above, 1+len*2 bytes will be reserved in the output buffer
  379. pxSCM->wExpLen += sizeof(UINT8) + len*2;
  380. }
  381. else
  382. {
  383. // This is equivalent to marshal a NULL & "len as a UINT8"
  384. NULL2XSCM(pxSCM);
  385. UINT82XSCM(pxSCM, len, TYPE_TYPED);
  386. }
  387. }
  388. void NULL2XSCM(LPXSCM pxSCM)
  389. {
  390. if (pxSCM->wExpLen + sizeof(UINT8) > pxSCM->wResLen)
  391. RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);
  392. // Prefix by the type (0)
  393. *((UINT8 *)pxSCM->pbBuffer)++ = 0;
  394. pxSCM->wExpLen += sizeof(UINT8);
  395. pxSCM->wGenLen += sizeof(UINT8);
  396. }