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.

549 lines
12 KiB

  1. // irda.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #define MAX_ATTRIB_LEN (64)
  5. CHAR* Hint1[]={"PnP",
  6. "PDA",
  7. "Computer",
  8. "Printer",
  9. "Modem",
  10. "Fax",
  11. "Lan",
  12. "Extension"
  13. };
  14. CHAR* Hint2[]={"Phone",
  15. "File server",
  16. "IrCOMM",
  17. "Message",
  18. "HTTP",
  19. "OBEX",
  20. "Unknown1",
  21. "Extension"
  22. };
  23. char* Classes[]={"IrDA:IrCOMM",
  24. "IrTranPv1",
  25. "IrDA:IrCOMM",
  26. "OBEX:IrXfer",
  27. "OBEX",
  28. "JetSend",
  29. "IrNetv1",
  30. "IrModem",
  31. "IrLAN",
  32. "IrLPT",
  33. "IrLPT",
  34. "IrTranPv1"
  35. };
  36. char* Attributes[]={"IrDA:TinyTP:LsapSel",
  37. "IrDA:TinyTP:LsapSel",
  38. "IrDA:IRLMP:LsapSel",
  39. "IrDA:TinyTP:LsapSel",
  40. "IrDA:TinyTP:LsapSel",
  41. "IrDA:TinyTP:LsapSel",
  42. "IrDA:TinyTP:LsapSel",
  43. "IrDA:TinyTP:LsapSel",
  44. "IrDA:TinyTP:LsapSel",
  45. "IrDA:IrLMP:LsapSel",
  46. "IrDA:IrLMP:lsapSel",
  47. "IrDA:TinyTP:LsapSel"
  48. };
  49. typedef enum {
  50. CLASS_IRCOMM,
  51. CLASS_OBEX,
  52. CLASS_Netv1,
  53. CLASS_IrModem
  54. } IRDA_CLASSES;
  55. int
  56. QueryIASForBinaryData(
  57. SOCKET QuerySock,
  58. u_char *pirdaDeviceID,
  59. char *pClassName,
  60. char *pAttribute,
  61. BYTE *Buffer,
  62. ULONG *BufferLength
  63. )
  64. {
  65. IAS_QUERY IASQuery;
  66. int QueryLength=sizeof(IASQuery);
  67. int Result;
  68. ZeroMemory(&IASQuery,sizeof(IASQuery));
  69. lstrcpyA(
  70. IASQuery.irdaClassName,
  71. pClassName
  72. );
  73. lstrcpyA(
  74. IASQuery.irdaAttribName,
  75. pAttribute
  76. );
  77. CopyMemory(
  78. &IASQuery.irdaDeviceID[0],
  79. pirdaDeviceID,
  80. 4
  81. );
  82. Result=getsockopt(
  83. QuerySock,
  84. SOL_IRLMP,
  85. IRLMP_IAS_QUERY,
  86. (char*)&IASQuery,
  87. &QueryLength
  88. );
  89. if (Result == SOCKET_ERROR) {
  90. return Result;
  91. }
  92. if (IASQuery.irdaAttribType != IAS_ATTRIB_OCTETSEQ) {
  93. return SOCKET_ERROR;
  94. }
  95. if (IASQuery.irdaAttribute.irdaAttribOctetSeq.Len > *BufferLength) {
  96. return SOCKET_ERROR;
  97. }
  98. CopyMemory(
  99. Buffer,
  100. &IASQuery.irdaAttribute.irdaAttribOctetSeq.OctetSeq[0],
  101. IASQuery.irdaAttribute.irdaAttribOctetSeq.Len
  102. );
  103. *BufferLength=IASQuery.irdaAttribute.irdaAttribOctetSeq.Len;
  104. return 0;
  105. }
  106. int
  107. QueryIASForInteger(SOCKET QuerySock,
  108. u_char *pirdaDeviceID,
  109. char *pClassName,
  110. char *pAttribute,
  111. int *pValue)
  112. {
  113. BYTE IASQueryBuff[sizeof(IAS_QUERY) - 3 + MAX_ATTRIB_LEN];
  114. int IASQueryLen = sizeof(IASQueryBuff);
  115. PIAS_QUERY pIASQuery = (PIAS_QUERY) &IASQueryBuff;
  116. RtlCopyMemory(&pIASQuery->irdaDeviceID[0], pirdaDeviceID, 4);
  117. lstrcpyA(&pIASQuery->irdaClassName[0], pClassName);
  118. lstrcpyA(&pIASQuery->irdaAttribName[0], pAttribute);
  119. if (getsockopt(QuerySock, SOL_IRLMP, IRLMP_IAS_QUERY,
  120. (char *) pIASQuery, &IASQueryLen) == SOCKET_ERROR)
  121. {
  122. #if 0
  123. printf("IRMON: IAS Query [\"%s\",\"%s\"] failed\n",
  124. pIASQuery->irdaClassName,
  125. pIASQuery->irdaAttribName
  126. );
  127. #endif
  128. return SOCKET_ERROR;
  129. }
  130. if (pIASQuery->irdaAttribType != IAS_ATTRIB_INT)
  131. {
  132. printf("IRMON: IAS Query [\"%s\",\"%s\"] irdaAttribType not int (%d)\n",
  133. pIASQuery->irdaClassName,
  134. pIASQuery->irdaAttribName,
  135. pIASQuery->irdaAttribType
  136. );
  137. return SOCKET_ERROR;
  138. }
  139. *pValue = pIASQuery->irdaAttribute.irdaAttribInt;
  140. return(0);
  141. }
  142. int
  143. QueryIASForString(SOCKET QuerySock,
  144. u_char *pirdaDeviceID,
  145. char *pClassName,
  146. char *pAttribute,
  147. char *pValue,
  148. int *pValueLen) // including trailing NULL
  149. {
  150. BYTE IASQueryBuff[sizeof(IAS_QUERY) - 3 + MAX_ATTRIB_LEN];
  151. int IASQueryLen = sizeof(IASQueryBuff);
  152. PIAS_QUERY pIASQuery = (PIAS_QUERY) &IASQueryBuff;
  153. RtlCopyMemory(&pIASQuery->irdaDeviceID[0], pirdaDeviceID, 4);
  154. lstrcpyA(&pIASQuery->irdaClassName[0], pClassName);
  155. lstrcpyA(&pIASQuery->irdaAttribName[0], pAttribute);
  156. if (getsockopt(QuerySock, SOL_IRLMP, IRLMP_IAS_QUERY,
  157. (char *) pIASQuery, &IASQueryLen) == SOCKET_ERROR)
  158. {
  159. // DEBUGMSG(("IRMON: IAS Query [\"%s\",\"%s\"] failed %ws\n",
  160. // pIASQuery->irdaClassName,
  161. // pIASQuery->irdaAttribName,
  162. // GetLastErrorText()));
  163. return SOCKET_ERROR;
  164. }
  165. if (pIASQuery->irdaAttribType != IAS_ATTRIB_STR)
  166. {
  167. // DEBUGMSG(("IRMON: IAS Query [\"%s\",\"%s\"] irdaAttribType not string (%d)\n",
  168. // pIASQuery->irdaClassName,
  169. // pIASQuery->irdaAttribName,
  170. // pIASQuery->irdaAttribType));
  171. return SOCKET_ERROR;
  172. }
  173. if (pIASQuery->irdaAttribute.irdaAttribUsrStr.CharSet != LmCharSetASCII)
  174. {
  175. // DEBUGMSG(("IRMON: IAS Query [\"%s\",\"%s\"] CharSet not ASCII (%d)\n",
  176. // pIASQuery->irdaClassName,
  177. // pIASQuery->irdaAttribName,
  178. // pIASQuery->irdaAttribute.irdaAttribUsrStr.CharSet));
  179. return SOCKET_ERROR;
  180. }
  181. // set ValueLen to data bytes to copy, allow room for NULL
  182. if (pIASQuery->irdaAttribute.irdaAttribUsrStr.Len + 1 >= (unsigned) *pValueLen)
  183. {
  184. // allow room for NULL
  185. (*pValueLen)--;
  186. }
  187. else
  188. {
  189. *pValueLen = pIASQuery->irdaAttribute.irdaAttribUsrStr.Len;
  190. }
  191. RtlCopyMemory(pValue, pIASQuery->irdaAttribute.irdaAttribUsrStr.UsrStr, *pValueLen);
  192. // append NULL
  193. pValue[(*pValueLen)++] = 0;
  194. return(0);
  195. }
  196. int __cdecl main(int argc, char* argv[])
  197. {
  198. SOCKET SocketHandle=INVALID_SOCKET;
  199. WORD WSAVerReq = MAKEWORD(2,0);
  200. WSADATA WSAData;
  201. INT Result;
  202. UCHAR Temp[4096];
  203. PDEVICELIST DeviceList=(PDEVICELIST)Temp;
  204. int DeviceListSize=sizeof(Temp);
  205. UINT i;
  206. Result=WSAStartup(
  207. WSAVerReq,
  208. &WSAData
  209. );
  210. if (Result != 0) {
  211. printf("WSAStartUp() Failed %d\n",Result);
  212. goto CleanUp;
  213. }
  214. SocketHandle=socket(
  215. AF_IRDA,
  216. SOCK_STREAM,
  217. 0
  218. );
  219. if (SocketHandle == INVALID_SOCKET) {
  220. printf("socket() faled %d\n",WSAGetLastError());
  221. }
  222. Result=getsockopt(
  223. SocketHandle,
  224. SOL_IRLMP,
  225. IRLMP_ENUMDEVICES,
  226. (char*)DeviceList,
  227. &DeviceListSize
  228. );
  229. if (Result == SOCKET_ERROR) {
  230. goto CleanUp;
  231. }
  232. printf("\n%d Irda devices found\n\n",DeviceList->numDevice);
  233. for (i=0; i< DeviceList->numDevice; i++) {
  234. PIRDA_DEVICE_INFO DeviceInfo=&DeviceList->Device[i];
  235. PULONG DeviceId=(PULONG)&DeviceInfo->irdaDeviceID;
  236. int LsapSel=-1;
  237. UINT j;
  238. int k;
  239. if ((DeviceInfo->irdaCharSet == 0xff)) {
  240. wprintf(L"Device Name(UNICODE): %s\n",&DeviceInfo->irdaDeviceName[0]);
  241. } else {
  242. printf("Device Name(ANSI): %s\n",&DeviceInfo->irdaDeviceName[0]);
  243. }
  244. printf("Hints:\n");
  245. for (j=0; j<7; j++) {
  246. if ( DeviceInfo->irdaDeviceHints1 & (1 << j)) {
  247. printf("\t%s\n",Hint1[j]);
  248. }
  249. }
  250. for (j=0; j<7; j++) {
  251. if ( DeviceInfo->irdaDeviceHints2 & (1 << j)) {
  252. printf("\t%s\n",Hint2[j]);
  253. }
  254. }
  255. printf("\nDoing IAS queries\n");
  256. for (j=0; j<sizeof(Classes)/sizeof(char*); j++) {
  257. Result=QueryIASForInteger(
  258. SocketHandle,
  259. &DeviceInfo->irdaDeviceID[0],
  260. Classes[j],
  261. Attributes[j],
  262. &LsapSel
  263. );
  264. if (Result == 0) {
  265. printf("\tResult for %13s -- %s : %d\n",Classes[j],Attributes[j],LsapSel);
  266. }
  267. }
  268. if ((DeviceInfo->irdaDeviceHints2 & 4) || (DeviceInfo->irdaDeviceHints1 & LM_HB1_Printer)) {
  269. BYTE Buffer[4096];
  270. ULONG BufferLength=sizeof(Buffer);
  271. CHAR InstanceName[256];
  272. int InstanceLength;
  273. printf("\nChecking for IrComm Parameters\n");
  274. Result=QueryIASForBinaryData(
  275. SocketHandle,
  276. &DeviceInfo->irdaDeviceID[0],
  277. Classes[0],
  278. "Parameters",
  279. &Buffer[0],
  280. &BufferLength
  281. );
  282. if (Result == 0) {
  283. ULONG k;
  284. for (k=0; k < BufferLength; ) {
  285. switch (Buffer[k]) {
  286. case 0:
  287. printf("\tServiceType- %s, %s, %s, %s\n",
  288. Buffer[k+2] & 1 ? "3 Wire raw" : "",
  289. Buffer[k+2] & 2 ? "3 Wire" : "",
  290. Buffer[k+2] & 4 ? "9 Wire" : "",
  291. Buffer[k+2] & 8 ? "Centronics" : ""
  292. );
  293. break;
  294. case 1:
  295. printf("\tPort Type- %s, %s\n",
  296. Buffer[k+2] & 1 ? "Serial" : "",
  297. Buffer[k+2] & 2 ? "Parallel" : ""
  298. );
  299. break;
  300. case 2:
  301. printf("\tPort Name- %s\n",&Buffer[k+2]);
  302. break;
  303. default:
  304. printf("\tPI=%x, pl=%d\n",Buffer[k],Buffer[k+1]);
  305. break;
  306. }
  307. k+=Buffer[k+1]+2;
  308. }
  309. }
  310. InstanceLength=sizeof(InstanceName);
  311. Result=QueryIASForString(
  312. SocketHandle,
  313. &DeviceInfo->irdaDeviceID[0],
  314. Classes[0],
  315. "IrDA:IrLMP:InstanceName",
  316. &InstanceName[0],
  317. &InstanceLength
  318. );
  319. if (Result == 0) {
  320. printf("\tInstanceName: %s\n",InstanceName);
  321. }
  322. }
  323. if (1) {
  324. //if (DeviceInfo->irdaDeviceHints1 & LM_HB1_PnP) {
  325. CHAR DeviceId[100];
  326. int BufferSize=sizeof(DeviceId);
  327. int CompatIds=0;
  328. printf("\nChecking PnP parameters\n");
  329. Result=QueryIASForString(
  330. SocketHandle,
  331. &DeviceInfo->irdaDeviceID[0],
  332. "PnP",
  333. "Name",
  334. DeviceId,
  335. &BufferSize
  336. );
  337. if (Result == 0) {
  338. printf("\tName: %s\n",DeviceId);
  339. }
  340. BufferSize=sizeof(DeviceId);
  341. Result=QueryIASForString(
  342. SocketHandle,
  343. &DeviceInfo->irdaDeviceID[0],
  344. "PnP",
  345. "Manufacturer",
  346. DeviceId,
  347. &BufferSize
  348. );
  349. if (Result == 0) {
  350. printf("\tManufactured by: %s\n",DeviceId);
  351. }
  352. BufferSize=sizeof(DeviceId);
  353. Result=QueryIASForString(
  354. SocketHandle,
  355. &DeviceInfo->irdaDeviceID[0],
  356. "PnP",
  357. "DeviceID",
  358. DeviceId,
  359. &BufferSize
  360. );
  361. if (Result == 0) {
  362. printf("\tPnP device id is %s\n",DeviceId);
  363. }
  364. Result=QueryIASForInteger(
  365. SocketHandle,
  366. &DeviceInfo->irdaDeviceID[0],
  367. "PnP",
  368. "CompCnt",
  369. &CompatIds
  370. );
  371. if (Result == 0) {
  372. printf("\tDevice has %d compatible ids\n",CompatIds);
  373. }
  374. for (k=0; k<CompatIds; k++) {
  375. CHAR Attribute[100];
  376. wsprintfA(Attribute,"Comp#%02d",k+1);
  377. BufferSize=sizeof(DeviceId);
  378. Result=QueryIASForString(
  379. SocketHandle,
  380. &DeviceInfo->irdaDeviceID[0],
  381. "PnP",
  382. Attribute,
  383. DeviceId,
  384. &BufferSize
  385. );
  386. if (Result == 0) {
  387. printf("\tCompatible id for %s, device id is %s\n",Attribute,DeviceId);
  388. } else {
  389. printf("\tcould not get Compatible id for %s\n",Attribute);
  390. }
  391. }
  392. }
  393. printf("\n");
  394. }
  395. CleanUp:
  396. return 0;
  397. }