Source code of Windows XP (NT5)
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.

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