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.

465 lines
12 KiB

  1. #define UNICODE 1
  2. #include <ntosp.h>
  3. #include <zwapi.h>
  4. #include <tdikrnl.h>
  5. #define UINT ULONG //tmp
  6. #include <irioctl.h>
  7. #include <ircommtdi.h>
  8. #include <ircommdbg.h>
  9. NTSTATUS
  10. IrdaOpenControlChannel(
  11. HANDLE *ControlHandle
  12. )
  13. {
  14. NTSTATUS Status;
  15. IO_STATUS_BLOCK Iosb;
  16. OBJECT_ATTRIBUTES ObjectAttributes;
  17. UNICODE_STRING DeviceName;
  18. RtlInitUnicodeString(&DeviceName, IRDA_DEVICE_NAME);
  19. InitializeObjectAttributes(&ObjectAttributes, &DeviceName,
  20. OBJ_CASE_INSENSITIVE, NULL, NULL);
  21. Status = ZwCreateFile(
  22. ControlHandle,
  23. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  24. &ObjectAttributes,
  25. &Iosb, // returned status information.
  26. 0, // block size (unused).
  27. 0, // file attributes.
  28. FILE_SHARE_READ | FILE_SHARE_WRITE,
  29. FILE_CREATE, // create disposition.
  30. 0, // create options.
  31. NULL,
  32. 0
  33. );
  34. return Status;
  35. }
  36. NTSTATUS
  37. IrdaDiscoverDevices(
  38. PDEVICELIST pDevList,
  39. PULONG pDevListLen
  40. )
  41. {
  42. NTSTATUS Status;
  43. IO_STATUS_BLOCK Iosb;
  44. HANDLE ControlHandle;
  45. OBJECT_ATTRIBUTES ObjectAttributes;
  46. UNICODE_STRING DeviceName;
  47. RtlInitUnicodeString(&DeviceName, IRDA_DEVICE_NAME);
  48. InitializeObjectAttributes(&ObjectAttributes, &DeviceName,
  49. OBJ_CASE_INSENSITIVE, NULL, NULL);
  50. Status = ZwCreateFile(
  51. &ControlHandle,
  52. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  53. &ObjectAttributes,
  54. &Iosb, // returned status information.
  55. 0, // block size (unused).
  56. 0, // file attributes.
  57. FILE_SHARE_READ | FILE_SHARE_WRITE,
  58. FILE_CREATE, // create disposition.
  59. 0, // create options.
  60. NULL,
  61. 0
  62. );
  63. Status = ZwDeviceIoControlFile(
  64. ControlHandle,
  65. NULL, // EventHandle
  66. NULL, // APC Routine
  67. NULL, // APC Context
  68. &Iosb,
  69. IOCTL_IRDA_GET_INFO_ENUM_DEV,
  70. pDevList,
  71. *pDevListLen,
  72. pDevList, // OutputBuffer
  73. *pDevListLen // OutputBufferLength
  74. );
  75. if (Status == STATUS_PENDING )
  76. {
  77. Status = ZwWaitForSingleObject(ControlHandle, TRUE, NULL);
  78. ASSERT(NT_SUCCESS(Status) );
  79. Status = Iosb.Status;
  80. }
  81. ZwClose(ControlHandle);
  82. return Status;
  83. }
  84. NTSTATUS
  85. IrdaIASStringQuery(
  86. ULONG DeviceID,
  87. PSTR ClassName,
  88. PSTR AttributeName,
  89. PWSTR *ReturnString
  90. )
  91. {
  92. NTSTATUS Status;
  93. IO_STATUS_BLOCK Iosb;
  94. HANDLE AddressHandle;
  95. IAS_QUERY IasQuery;
  96. *ReturnString=NULL;
  97. Status=IrdaOpenControlChannel(&AddressHandle);
  98. if (!NT_SUCCESS(Status)) {
  99. D_ERROR(DbgPrint("IRCOMM: IrdaCreateAddress() failed %08lx\n",Status);)
  100. return Status;
  101. }
  102. RtlCopyMemory(&IasQuery.irdaDeviceID[0],&DeviceID,sizeof(IasQuery.irdaDeviceID));
  103. strcpy(IasQuery.irdaClassName,ClassName);
  104. strcpy(IasQuery.irdaAttribName,AttributeName);
  105. Status = ZwDeviceIoControlFile(
  106. AddressHandle,
  107. NULL, // EventHandle
  108. NULL, // APC Routine
  109. NULL, // APC Context
  110. &Iosb,
  111. IOCTL_IRDA_QUERY_IAS,
  112. &IasQuery,
  113. sizeof(IasQuery),
  114. &IasQuery, // OutputBuffer
  115. sizeof(IasQuery) // OutputBufferLength
  116. );
  117. if (Status == STATUS_PENDING ) {
  118. ZwWaitForSingleObject(AddressHandle, TRUE, NULL);
  119. Status = Iosb.Status;
  120. }
  121. ZwClose(AddressHandle);
  122. if (!NT_SUCCESS(Status)) {
  123. return Status;
  124. }
  125. {
  126. WCHAR TempBuffer[IAS_MAX_USER_STRING+1];
  127. UNICODE_STRING UnicodeString;
  128. UnicodeString.Length=0;
  129. if (IasQuery.irdaAttribute.irdaAttribUsrStr.CharSet == LmCharSetUNICODE) {
  130. UnicodeString.MaximumLength=(USHORT)(IasQuery.irdaAttribute.irdaAttribUsrStr.Len+1);
  131. } else {
  132. UnicodeString.MaximumLength=(USHORT)(IasQuery.irdaAttribute.irdaAttribUsrStr.Len+1)*sizeof(WCHAR);
  133. }
  134. UnicodeString.Buffer=ALLOCATE_PAGED_POOL(UnicodeString.MaximumLength);
  135. if (UnicodeString.Buffer == NULL) {
  136. return STATUS_INSUFFICIENT_RESOURCES;
  137. }
  138. RtlZeroMemory(UnicodeString.Buffer,UnicodeString.MaximumLength);
  139. //
  140. // zero out the temp buffer, so we can copy the remote device name,
  141. // so we can be sure it is null terminated
  142. //
  143. RtlZeroMemory(TempBuffer,sizeof(TempBuffer));
  144. RtlCopyMemory(TempBuffer,IasQuery.irdaAttribute.irdaAttribUsrStr.UsrStr,IasQuery.irdaAttribute.irdaAttribUsrStr.Len);
  145. if (IasQuery.irdaAttribute.irdaAttribUsrStr.CharSet == LmCharSetUNICODE) {
  146. //
  147. // the name is unicode
  148. //
  149. Status=RtlAppendUnicodeToString(&UnicodeString,TempBuffer);
  150. } else {
  151. //
  152. // the name is ansi, need to convert unicode
  153. //
  154. ANSI_STRING AnsiString;
  155. RtlInitAnsiString(
  156. &AnsiString,
  157. (PCSZ)TempBuffer
  158. );
  159. Status=RtlAnsiStringToUnicodeString(
  160. &UnicodeString,
  161. &AnsiString,
  162. FALSE
  163. );
  164. }
  165. if (NT_SUCCESS(Status)) {
  166. *ReturnString=UnicodeString.Buffer;
  167. } else {
  168. FREE_POOL(UnicodeString.Buffer);
  169. }
  170. }
  171. return Status;
  172. }
  173. NTSTATUS
  174. IrdaIASIntegerQuery(
  175. ULONG DeviceID,
  176. PSTR ClassName,
  177. PSTR AttributeName,
  178. LONG *ReturnValue
  179. )
  180. {
  181. NTSTATUS Status;
  182. IO_STATUS_BLOCK Iosb;
  183. HANDLE AddressHandle;
  184. IAS_QUERY IasQuery;
  185. *ReturnValue=0;
  186. Status=IrdaOpenControlChannel(&AddressHandle);
  187. if (!NT_SUCCESS(Status)) {
  188. D_ERROR(DbgPrint("IRCOMM: IrdaCreateAddress() failed %08lx\n",Status);)
  189. return Status;
  190. }
  191. RtlCopyMemory(&IasQuery.irdaDeviceID[0],&DeviceID,sizeof(IasQuery.irdaDeviceID));
  192. strcpy(IasQuery.irdaClassName,ClassName);
  193. strcpy(IasQuery.irdaAttribName,AttributeName);
  194. Status = ZwDeviceIoControlFile(
  195. AddressHandle,
  196. NULL, // EventHandle
  197. NULL, // APC Routine
  198. NULL, // APC Context
  199. &Iosb,
  200. IOCTL_IRDA_QUERY_IAS,
  201. &IasQuery,
  202. sizeof(IasQuery),
  203. &IasQuery, // OutputBuffer
  204. sizeof(IasQuery) // OutputBufferLength
  205. );
  206. if (Status == STATUS_PENDING ) {
  207. ZwWaitForSingleObject(AddressHandle, TRUE, NULL);
  208. Status = Iosb.Status;
  209. }
  210. ZwClose(AddressHandle);
  211. if (!NT_SUCCESS(Status)) {
  212. return Status;
  213. }
  214. if (IasQuery.irdaAttribType != IAS_ATTRIB_INT) {
  215. return STATUS_UNSUCCESSFUL;
  216. }
  217. *ReturnValue=IasQuery.irdaAttribute.irdaAttribInt;
  218. return STATUS_SUCCESS;
  219. }
  220. NTSTATUS
  221. IrdaIASStringSet(
  222. HANDLE AddressHandle,
  223. PSTR ClassName,
  224. PSTR AttributeName,
  225. PSTR StringToSet
  226. )
  227. {
  228. NTSTATUS Status;
  229. IO_STATUS_BLOCK Iosb;
  230. IAS_SET IasSet;
  231. strcpy(IasSet.irdaClassName,ClassName);
  232. strcpy(IasSet.irdaAttribName,AttributeName);
  233. IasSet.irdaAttribType=IAS_ATTRIB_STR;
  234. IasSet.irdaAttribute.irdaAttribUsrStr.CharSet=LmCharSetASCII;
  235. IasSet.irdaAttribute.irdaAttribUsrStr.Len=(UCHAR)strlen(StringToSet);
  236. strcpy(IasSet.irdaAttribute.irdaAttribUsrStr.UsrStr,StringToSet);
  237. Status = ZwDeviceIoControlFile(
  238. AddressHandle,
  239. NULL, // EventHandle
  240. NULL, // APC Routine
  241. NULL, // APC Context
  242. &Iosb,
  243. IOCTL_IRDA_SET_IAS,
  244. &IasSet,
  245. sizeof(IasSet),
  246. &IasSet, // OutputBuffer
  247. sizeof(IasSet) // OutputBufferLength
  248. );
  249. if (Status == STATUS_PENDING ) {
  250. ZwWaitForSingleObject(AddressHandle, TRUE, NULL);
  251. Status = Iosb.Status;
  252. }
  253. if (!NT_SUCCESS(Status)) {
  254. D_ERROR(DbgPrint("IRENUM:IrdaIASStringSet() failed %08lx\n",Status);)
  255. }
  256. return Status;
  257. }
  258. NTSTATUS
  259. IrdaIASOctetSet(
  260. PFILE_OBJECT FileObject,
  261. PSTR ClassName,
  262. PSTR AttributeName,
  263. PUCHAR Value,
  264. ULONG ValueLength
  265. )
  266. {
  267. NTSTATUS Status;
  268. IO_STATUS_BLOCK Iosb;
  269. IAS_SET IasSet;
  270. KEVENT Event;
  271. PIRP Irp;
  272. PIO_STACK_LOCATION IrpSp;
  273. KeInitializeEvent(&Event,NotificationEvent,FALSE);
  274. strcpy(IasSet.irdaClassName,ClassName);
  275. strcpy(IasSet.irdaAttribName,AttributeName);
  276. IasSet.irdaAttribType=IAS_ATTRIB_OCTETSEQ;
  277. IasSet.irdaAttribute.irdaAttribOctetSeq.Len=(USHORT)ValueLength;
  278. RtlCopyMemory(&IasSet.irdaAttribute.irdaAttribOctetSeq.OctetSeq,Value,ValueLength);
  279. Irp=IoBuildDeviceIoControlRequest(
  280. IOCTL_IRDA_SET_IAS,
  281. IoGetRelatedDeviceObject(FileObject),
  282. &IasSet,
  283. sizeof(IasSet),
  284. NULL,
  285. 0,
  286. FALSE,
  287. &Event,
  288. &Iosb
  289. );
  290. if (Irp == NULL) {
  291. return STATUS_INSUFFICIENT_RESOURCES;
  292. }
  293. IrpSp=IoGetNextIrpStackLocation(Irp);
  294. IrpSp->FileObject=FileObject;
  295. IoCallDriver(
  296. IoGetRelatedDeviceObject(FileObject),
  297. Irp
  298. );
  299. KeWaitForSingleObject(
  300. &Event,
  301. Executive,
  302. KernelMode,
  303. FALSE,
  304. NULL
  305. );
  306. //
  307. // get the final status from the io request
  308. //
  309. Status = Iosb.Status;
  310. if (!NT_SUCCESS(Status)) {
  311. D_ERROR(DbgPrint("IRCOMM:IrdaIASOctetSet() failed %08lx\n",Status);)
  312. }
  313. //
  314. // the irp is completed and freed by the os
  315. //
  316. return Status;
  317. }
  318. VOID
  319. IrdaLazyDiscoverDevices(
  320. HANDLE ControlHandle,
  321. HANDLE Event,
  322. PIO_STATUS_BLOCK Iosb,
  323. PDEVICELIST pDevList,
  324. ULONG DevListLen
  325. )
  326. {
  327. ZwDeviceIoControlFile(
  328. ControlHandle,
  329. Event, // EventHandle
  330. NULL, // APC Routine
  331. NULL, // APC Context
  332. Iosb,
  333. IOCTL_IRDA_LAZY_DISCOVERY,
  334. NULL,
  335. 0,
  336. pDevList, // OutputBuffer
  337. DevListLen // OutputBufferLength
  338. );
  339. return;
  340. }