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.

302 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. Nds32W95.c
  5. Abstract:
  6. This module implements functions to Read, Add, Modify, and Remove
  7. NDS Objects and Attributes using the Microsoft Netware redirector.
  8. All functions in this file are NT specific.
  9. Author:
  10. Glenn Curtis [GlennC] 04-Jan-1996
  11. Glenn Curtis [GlennC] 24-Apr-1996 - Added schema APIs
  12. Glenn Curtis [GlennC] 20-Jun-1996 - Added search API
  13. Felix Wong [t-felixw] 24-Sep-1996 - Added Win95 Support
  14. --*/
  15. #include <procs.h>
  16. #ifdef WIN95
  17. #include <msnwapi.h>
  18. #include <utils95.h>
  19. #include <nw95.h>
  20. char ROOT_STR[] = "[Root]";
  21. #endif
  22. typedef struct
  23. {
  24. DWORD Signature;
  25. HANDLE NdsTree;
  26. DWORD ObjectId;
  27. DWORD ResumeId;
  28. DWORD NdsRawDataBuffer;
  29. DWORD NdsRawDataSize;
  30. DWORD NdsRawDataId;
  31. DWORD NdsRawDataCount;
  32. WCHAR Name[1];
  33. } NDS_OBJECT, * LPNDS_OBJECT;
  34. //
  35. // Flags used for the function ParseNdsUncPath()
  36. //
  37. #define PARSE_NDS_GET_TREE_NAME 0
  38. #define PARSE_NDS_GET_PATH_NAME 1
  39. #define PARSE_NDS_GET_OBJECT_NAME 2
  40. WORD
  41. ParseNdsUncPath( IN OUT LPWSTR * Result,
  42. IN LPWSTR ObjectPathName,
  43. IN DWORD flag );
  44. DWORD
  45. GetFirstNdsSubTreeEntry(
  46. OUT LPNDS_OBJECT lpNdsObject,
  47. IN DWORD BufferSize )
  48. {
  49. UNICODE_STRING UName;
  50. LPSTR szName;
  51. struct _nds_tag *pBufTag;
  52. PBYTE LocalBuffer;
  53. UINT nObjects;
  54. DWORD* pBuffer;
  55. NW_STATUS nwstatus;
  56. NTSTATUS ntstatus = STATUS_UNSUCCESSFUL;
  57. lpNdsObject->NdsRawDataSize = BufferSize;
  58. //
  59. // Determine size of NDS raw data buffer to use. Set to at least 8KB.
  60. //
  61. if ( lpNdsObject->NdsRawDataSize < 8192 )
  62. lpNdsObject->NdsRawDataSize = 8192;
  63. //
  64. // Create NDS raw data buffer.
  65. //
  66. lpNdsObject->NdsRawDataBuffer = (DWORD) LocalAlloc( LMEM_ZEROINIT,
  67. lpNdsObject->NdsRawDataSize );
  68. LocalBuffer = (PBYTE)LocalAlloc( LMEM_ZEROINIT,lpNdsObject->NdsRawDataSize );
  69. if ( lpNdsObject->NdsRawDataBuffer == 0 || LocalBuffer == 0)
  70. {
  71. KdPrint(("NWWORKSTATION: NwGetFirstNdsSubTreeEntry LocalAlloc Failed %lu\n", GetLastError()));
  72. ntstatus = STATUS_NO_MEMORY;
  73. goto Exit;
  74. }
  75. //
  76. // Set up to get initial NDS subordinate list.
  77. //
  78. lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
  79. RtlInitUnicodeString( &UName, lpNdsObject->Name );
  80. UName.Length = ParseNdsUncPath( (LPWSTR *) &UName.Buffer,
  81. lpNdsObject->Name,
  82. PARSE_NDS_GET_PATH_NAME );
  83. if ( UName.Length == 0 )
  84. {
  85. szName = (LPSTR)LocalAlloc( LPTR, sizeof(char) * (strlen(ROOT_STR) + 1));
  86. if (szName == NULL) {
  87. ntstatus = STATUS_NO_MEMORY;
  88. goto Exit;
  89. };
  90. strcpy(szName,ROOT_STR);
  91. }
  92. else
  93. {
  94. szName = AllocateAnsiString(UName.Buffer);
  95. if (szName == NULL) {
  96. ntstatus = STATUS_NO_MEMORY;
  97. goto Exit;
  98. };
  99. }
  100. nwstatus = NDSListSubordinates(
  101. szName,
  102. LocalBuffer,
  103. lpNdsObject->NdsRawDataSize,
  104. &lpNdsObject->NdsRawDataId,
  105. &nObjects
  106. );
  107. ntstatus = MapNwToNtStatus(nwstatus);
  108. if ( ntstatus == STATUS_SUCCESS) {
  109. pBufTag = (struct _nds_tag *)LocalBuffer;
  110. pBuffer = (DWORD*)lpNdsObject->NdsRawDataBuffer;
  111. *pBuffer++ = (DWORD)ntstatus;
  112. *pBuffer++ = (DWORD)lpNdsObject->NdsRawDataId;
  113. *pBuffer++ = (DWORD)nObjects;
  114. memcpy( (LPBYTE)pBuffer,
  115. (char *)pBufTag->nextItem,
  116. pBufTag->bufEnd - (char *)pBufTag->nextItem);
  117. if (((PNDS_RESPONSE_SUBORDINATE_LIST)
  118. lpNdsObject->NdsRawDataBuffer)->SubordinateEntries != 0 ) {
  119. lpNdsObject->NdsRawDataCount = ((PNDS_RESPONSE_SUBORDINATE_LIST)
  120. lpNdsObject->NdsRawDataBuffer)->SubordinateEntries - 1;
  121. lpNdsObject->ResumeId = lpNdsObject->NdsRawDataBuffer +
  122. sizeof(NDS_RESPONSE_SUBORDINATE_LIST);
  123. // Successful exit
  124. goto Exit;
  125. }
  126. }
  127. // No entries
  128. lpNdsObject->NdsRawDataBuffer = 0;
  129. lpNdsObject->NdsRawDataSize = 0;
  130. lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
  131. lpNdsObject->NdsRawDataCount = 0;
  132. lpNdsObject->ResumeId = 0;
  133. ntstatus = STATUS_NO_MORE_ENTRIES;
  134. Exit:
  135. if (szName)
  136. LocalFree(szName);
  137. if (LocalBuffer)
  138. LocalFree(LocalBuffer);
  139. if (ntstatus != STATUS_SUCCESS) {
  140. if ( lpNdsObject->NdsRawDataBuffer )
  141. (void) LocalFree( (HLOCAL) lpNdsObject->NdsRawDataBuffer );
  142. }
  143. return RtlNtStatusToDosError(ntstatus);
  144. }
  145. DWORD
  146. GetNextNdsSubTreeEntry(
  147. OUT LPNDS_OBJECT lpNdsObject )
  148. {
  149. NTSTATUS nwstatus;
  150. NTSTATUS ntstatus = STATUS_SUCCESS;
  151. struct _nds_tag *pBufTag;
  152. PBYTE pbRaw;
  153. DWORD dwStrLen;
  154. LPSTR szName;
  155. UINT nObjects;
  156. DWORD *pBuffer;
  157. if ( lpNdsObject->NdsRawDataCount == 0 &&
  158. lpNdsObject->NdsRawDataId == INITIAL_ITERATION )
  159. return WN_NO_MORE_ENTRIES;
  160. if ( lpNdsObject->NdsRawDataCount == 0 &&
  161. lpNdsObject->NdsRawDataId != INITIAL_ITERATION )
  162. {
  163. PBYTE LocalBuffer;
  164. UNICODE_STRING UName;
  165. LocalBuffer = (PBYTE) LocalAlloc( LMEM_ZEROINIT,lpNdsObject->NdsRawDataSize );
  166. if ( lpNdsObject->NdsRawDataBuffer == 0 || LocalBuffer == 0)
  167. {
  168. KdPrint(("NWWORKSTATION: NwGetFirstNdsSubTreeEntry LocalAlloc Failed %lu\n", GetLastError()));
  169. ntstatus = STATUS_NO_MEMORY;
  170. goto Exit;
  171. }
  172. RtlInitUnicodeString( &UName, lpNdsObject->Name );
  173. UName.Length = ParseNdsUncPath( (LPWSTR *) &UName.Buffer,
  174. lpNdsObject->Name,
  175. PARSE_NDS_GET_PATH_NAME );
  176. if ( UName.Length == 0 )
  177. {
  178. szName = (LPSTR)LocalAlloc( LPTR, sizeof(char) * (strlen(ROOT_STR) + 1));
  179. if (szName == NULL) {
  180. ntstatus = STATUS_NO_MEMORY;
  181. goto Exit;
  182. };
  183. strcpy(szName,ROOT_STR);
  184. }
  185. else
  186. {
  187. szName = AllocateAnsiString(UName.Buffer);
  188. if (szName == NULL) {
  189. ntstatus = STATUS_NO_MEMORY;
  190. goto Exit;
  191. };
  192. }
  193. nwstatus = NDSListSubordinates(
  194. szName,
  195. (LPBYTE)LocalBuffer,
  196. lpNdsObject->NdsRawDataSize,
  197. &lpNdsObject->NdsRawDataId,
  198. &nObjects
  199. );
  200. ntstatus = MapNwToNtStatus(nwstatus);
  201. if (ntstatus == STATUS_SUCCESS) {
  202. pBufTag = (struct _nds_tag *)LocalBuffer;
  203. pBuffer = (DWORD*)lpNdsObject->NdsRawDataBuffer;
  204. *pBuffer++ = (DWORD)ntstatus;
  205. *pBuffer++ = (DWORD)lpNdsObject->NdsRawDataId;
  206. *pBuffer++ = (DWORD)nObjects;
  207. memcpy( (LPBYTE)pBuffer,
  208. (char *)pBufTag->nextItem,
  209. pBufTag->bufEnd - (char *)pBufTag->nextItem);
  210. lpNdsObject->NdsRawDataCount = ((PNDS_RESPONSE_SUBORDINATE_LIST)
  211. lpNdsObject->NdsRawDataBuffer)->SubordinateEntries - 1;
  212. lpNdsObject->ResumeId = lpNdsObject->NdsRawDataBuffer +
  213. sizeof(NDS_RESPONSE_SUBORDINATE_LIST);
  214. }
  215. Exit:
  216. if (LocalBuffer)
  217. LocalFree(LocalBuffer);
  218. if (szName)
  219. LocalFree(szName);
  220. if (ntstatus != STATUS_SUCCESS)
  221. {
  222. if ( lpNdsObject->NdsRawDataBuffer )
  223. (void) LocalFree( (HLOCAL) lpNdsObject->NdsRawDataBuffer );
  224. lpNdsObject->NdsRawDataBuffer = 0;
  225. lpNdsObject->NdsRawDataSize = 0;
  226. lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
  227. lpNdsObject->NdsRawDataCount = 0;
  228. return WN_NO_MORE_ENTRIES;
  229. }
  230. return RtlNtStatusToDosError(ntstatus);
  231. }
  232. lpNdsObject->NdsRawDataCount--;
  233. //
  234. // Move pointer past the fixed header portion of a
  235. // NDS_RESPONSE_SUBORDINATE_ENTRY
  236. //
  237. pbRaw = (BYTE *) lpNdsObject->ResumeId;
  238. pbRaw += sizeof(NDS_RESPONSE_SUBORDINATE_ENTRY);
  239. //
  240. // Move pointer past the length value of the Class Name string
  241. // of a NDS_RESPONSE_SUBORDINATE_ENTRY
  242. //
  243. dwStrLen = * (DWORD *) pbRaw;
  244. pbRaw += sizeof(DWORD);
  245. //
  246. // Move pointer past the Class Name string of a
  247. // NDS_RESPONSE_SUBORDINATE_ENTRY
  248. //
  249. pbRaw += ROUNDUP4( dwStrLen );
  250. //
  251. // Move pointer past the length value of the Object Name string
  252. // of a NDS_RESPONSE_SUBORDINATE_ENTRY
  253. //
  254. dwStrLen = * (DWORD *) pbRaw;
  255. pbRaw += sizeof(DWORD);
  256. lpNdsObject->ResumeId = (DWORD) ( pbRaw + ROUNDUP4( dwStrLen ) );
  257. return RtlNtStatusToDosError(ntstatus);
  258. }