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.

385 lines
9.2 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1992, Microsoft Corporation.
  4. //
  5. // File: enumnode.cxx
  6. //
  7. // Contents: This has the implementation for enumeration helper classes
  8. // CDfsEnumNode, CDfsEnumHandleTable.
  9. //
  10. // Functions:
  11. //
  12. // History: 21-June-1994 SudK Created.
  13. //
  14. //-----------------------------------------------------------------------------
  15. extern "C"
  16. {
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #include <ntlsa.h>
  21. }
  22. #include <dfsfsctl.h>
  23. #include <windows.h>
  24. #include <string.h>
  25. #include <wchar.h>
  26. #include <npapi.h>
  27. #include <lm.h>
  28. #define appDebugOut(x)
  29. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  30. #define INCL_NETLIB
  31. #include <lmui.hxx>
  32. #include <dfsutil.hxx>
  33. #include "dfsenum.hxx"
  34. ///////////////////////////////////////////////////////////////////////////////
  35. ///////////////////////////////////////////////////////////////////////////////
  36. //+-------------------------------------------------------------------------
  37. //
  38. // Method: CDfsEnumNode::CDfsEnumNode
  39. //
  40. // Synopsis: Constructor for this enumeration node.
  41. //
  42. // Returns: Nothing
  43. //
  44. //--------------------------------------------------------------------------
  45. CDfsEnumNode::CDfsEnumNode(
  46. DWORD dwScope,
  47. DWORD dwType,
  48. DWORD dwUsage
  49. )
  50. :
  51. _dwScope(dwScope),
  52. _dwType(dwType),
  53. _dwUsage(dwUsage)
  54. {
  55. }
  56. //+-------------------------------------------------------------------------
  57. //
  58. // Method: CDfsEnumNode::~CDfsEnumNode
  59. //
  60. // Synopsis: Destructor.
  61. //
  62. // Returns: Nothing
  63. //
  64. //--------------------------------------------------------------------------
  65. CDfsEnumNode::~CDfsEnumNode()
  66. {
  67. //
  68. // Nothing to do
  69. //
  70. }
  71. ///////////////////////////////////////////////////////////////////////////////
  72. ///////////////////////////////////////////////////////////////////////////////
  73. //+-------------------------------------------------------------------------
  74. //
  75. // Method: CDfsEnumConnectedNode::CDfsEnumConnectedNode
  76. //
  77. // Synopsis: Constructor for this enumeration node.
  78. //
  79. // Returns: Nothing
  80. //
  81. //--------------------------------------------------------------------------
  82. #define OFFSET_TO_POINTER(p, o) \
  83. if ((o)) *((LPBYTE *) &(o)) = (((LPBYTE) (o)) + ((DWORD_PTR) (p)))
  84. CDfsEnumConnectedNode::CDfsEnumConnectedNode(
  85. DWORD dwScope,
  86. DWORD dwType,
  87. DWORD dwUsage,
  88. LPCTSTR pszProviderName,
  89. const LPNETRESOURCE lpNetResource
  90. )
  91. :
  92. CDfsEnumNode(dwScope, dwType, dwUsage),
  93. _iNext(0),
  94. _cTotal(0),
  95. _lpNetResource(NULL)
  96. {
  97. NTSTATUS Status;
  98. DWORD cbSize;
  99. //
  100. // We are only going to enumerate disk resources.
  101. //
  102. if ((dwType != RESOURCETYPE_ANY) &&
  103. ((dwType & RESOURCETYPE_DISK) == 0))
  104. return;
  105. _lpNetResource = (LPNETRESOURCE) _buffer;
  106. cbSize = sizeof(_buffer);
  107. do {
  108. Status = DfsFsctl(
  109. FSCTL_DFS_GET_CONNECTED_RESOURCES,
  110. (PVOID) pszProviderName,
  111. (strlenf( pszProviderName ) + 1) * sizeof(TCHAR),
  112. (PVOID) _lpNetResource,
  113. cbSize,
  114. NULL);
  115. if (Status == STATUS_BUFFER_OVERFLOW) {
  116. if (_lpNetResource != (LPNETRESOURCE) _buffer) {
  117. delete _lpNetResource;
  118. }
  119. cbSize *= 2;
  120. _lpNetResource = (LPNETRESOURCE) new BYTE[ cbSize ];
  121. }
  122. } while ( Status == STATUS_BUFFER_OVERFLOW && _lpNetResource != NULL );
  123. if ( Status == STATUS_SUCCESS && _lpNetResource != NULL ) {
  124. _cTotal = *((LPDWORD)
  125. ( ((PUCHAR) _lpNetResource) + cbSize - sizeof(DWORD) ));
  126. for(DWORD i = 0; i < _cTotal; i++) {
  127. LPNETRESOURCE res;
  128. res = &_lpNetResource[i];
  129. OFFSET_TO_POINTER(_lpNetResource, res->lpProvider);
  130. OFFSET_TO_POINTER(_lpNetResource, res->lpComment);
  131. OFFSET_TO_POINTER(_lpNetResource, res->lpLocalName);
  132. OFFSET_TO_POINTER(_lpNetResource, res->lpRemoteName);
  133. }
  134. }
  135. }
  136. //+-------------------------------------------------------------------------
  137. //
  138. // Method: CDfsEnumConnectedNode::~CDfsEnumConnectedNode
  139. //
  140. // Synopsis: Destructor.
  141. //
  142. // Returns: Nothing
  143. //
  144. //--------------------------------------------------------------------------
  145. CDfsEnumConnectedNode::~CDfsEnumConnectedNode()
  146. {
  147. if (_lpNetResource != (LPNETRESOURCE) _buffer && _lpNetResource != NULL) {
  148. delete _lpNetResource;
  149. }
  150. }
  151. //+-------------------------------------------------------------------------
  152. //
  153. // Method: CDfsEnumConnectedNode::Init
  154. //
  155. // Synopsis: Do the actual enumeration here
  156. //
  157. // Returns: Nothing
  158. //
  159. //--------------------------------------------------------------------------
  160. DWORD
  161. CDfsEnumConnectedNode::Init(
  162. VOID
  163. )
  164. {
  165. return WN_SUCCESS;
  166. }
  167. //+----------------------------------------------------------------------------
  168. //
  169. // Method: CDfsEnumConnectedNode::PackString
  170. //
  171. // Synopsis: Packs a string into the end of a buffer, returning a pointer
  172. // to where the string was put.
  173. //
  174. // Arguments: [pBuffer] -- The Buffer to stuff into.
  175. //
  176. // [wszString] -- The string to stuff.
  177. //
  178. // [cbString] -- Size, in bytes of wszString, including
  179. // terminating NULL, if any.
  180. //
  181. // [lpcbBuf] -- On entry, contains size in bytes of pBuffer. On
  182. // return, this size is decremented by cbString.
  183. //
  184. // Returns: Pointer (into pBuffer) where wszString was stuffed.
  185. //
  186. //-----------------------------------------------------------------------------
  187. inline LPWSTR
  188. CDfsEnumConnectedNode::PackString(
  189. IN LPVOID pBuffer,
  190. IN LPCWSTR wszString,
  191. IN DWORD cbString,
  192. IN OUT LPDWORD lpcbBuf)
  193. {
  194. LPWSTR wszDest;
  195. ASSERT( cbString <= *lpcbBuf );
  196. ASSERT( cbString != 0 );
  197. wszDest = (LPWSTR) ( ((LPBYTE)pBuffer) + *lpcbBuf - cbString);
  198. MoveMemory( (PVOID) wszDest, wszString, cbString );
  199. (*lpcbBuf) -= cbString;
  200. return( wszDest );
  201. }
  202. //+-------------------------------------------------------------------------
  203. //
  204. // Method: CDfsEnumConnectedNode::GetNetResource
  205. //
  206. // Synopsis: Returns a single NETRESOURCE for a CONNECTED resource.
  207. //
  208. // Returns: Same error codes as WNetEnumResources.
  209. //
  210. //--------------------------------------------------------------------------
  211. DWORD
  212. CDfsEnumConnectedNode::GetNetResource(
  213. LPVOID lpBuffer,
  214. LPDWORD lpBufferSize
  215. )
  216. {
  217. DWORD cbRes, cbLocal, cbRemote, cbComment, cbProvider;
  218. LPNETRESOURCE res, dest;
  219. //
  220. // This call retrieves the next CONNECTED Resource from the list retrieved
  221. // in the constructor.
  222. //
  223. //
  224. // See if we are done
  225. //
  226. if (_iNext == _cTotal) {
  227. return( WN_NO_MORE_ENTRIES );
  228. }
  229. if (_lpNetResource == NULL) {
  230. return( ERROR_NOT_ENOUGH_MEMORY );
  231. }
  232. //
  233. // We have entries to return, so lets try to.
  234. //
  235. ASSERT(_iNext < _cTotal);
  236. res = &_lpNetResource[_iNext];
  237. //
  238. // First, determine the size of the strings and the total NETRESOURCE
  239. // to see if it will fit in the provided buffer.
  240. //
  241. cbLocal = cbRemote = cbComment = cbProvider = 0;
  242. if (res->lpLocalName) {
  243. cbLocal = (wcslen(res->lpLocalName) + 1) * sizeof(WCHAR);
  244. }
  245. if (res->lpRemoteName) {
  246. cbRemote = (wcslen(res->lpRemoteName) + 1) * sizeof(WCHAR);
  247. }
  248. if (res->lpComment) {
  249. cbComment = (wcslen(res->lpComment) + 1) * sizeof(WCHAR);
  250. }
  251. if (res->lpProvider) {
  252. cbProvider = (wcslen(res->lpProvider) + 1) * sizeof(WCHAR);
  253. }
  254. cbRes = sizeof(NETRESOURCE) + cbLocal + cbRemote + cbComment + cbProvider;
  255. if (cbRes > *lpBufferSize) {
  256. *lpBufferSize = cbRes;
  257. return( WN_MORE_DATA );
  258. }
  259. //
  260. // Ok, looks like this NETRESOURCE will fit. Stuff it into the user
  261. // buffer, packing strings at the end of the buffer
  262. //
  263. dest = (LPNETRESOURCE) lpBuffer;
  264. *dest = *res;
  265. if (res->lpProvider) {
  266. dest->lpProvider = PackString(
  267. lpBuffer,
  268. res->lpProvider,
  269. cbProvider,
  270. lpBufferSize);
  271. }
  272. if (res->lpComment) {
  273. dest->lpComment = PackString(
  274. lpBuffer,
  275. res->lpComment,
  276. cbComment,
  277. lpBufferSize);
  278. }
  279. if (res->lpRemoteName) {
  280. dest->lpRemoteName = PackString(
  281. lpBuffer,
  282. res->lpRemoteName,
  283. cbRemote,
  284. lpBufferSize);
  285. }
  286. if (res->lpLocalName) {
  287. res->lpLocalName = PackString(
  288. lpBuffer,
  289. res->lpLocalName,
  290. cbLocal,
  291. lpBufferSize);
  292. }
  293. //
  294. // Update our own records to indicate that we successfully returned one
  295. // more NETRESOURCE ...
  296. //
  297. _iNext++;
  298. //
  299. // And return.
  300. //
  301. return( WN_SUCCESS );
  302. }