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.

1002 lines
24 KiB

  1. /*++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. ifsmrxnp.c
  5. Abstract:
  6. This module implements the routines required for interaction with network
  7. provider router interface in NT
  8. Notes:
  9. This module has been built and tested only in UNICODE environment
  10. --*/
  11. #include <windows.h>
  12. #include <windef.h>
  13. #include <winbase.h>
  14. #include <winsvc.h>
  15. #include <winnetwk.h>
  16. #include <npapi.h>
  17. #include <devioctl.h>
  18. #include "nulmrx.h"
  19. #ifdef DBG
  20. #define DbgP(_x_) WideDbgPrint _x_
  21. #else
  22. #define DbgP(_x_)
  23. #endif
  24. ULONG _cdecl WideDbgPrint( PWCHAR Format, ... );
  25. #define TRACE_TAG L"NULMRXNP: "
  26. #define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
  27. DWORD APIENTRY
  28. NPGetCaps(
  29. DWORD nIndex )
  30. /*++
  31. Routine Description:
  32. This routine returns the capaboilities of the Null Mini redirector
  33. network provider implementation
  34. Arguments:
  35. nIndex - category of capabilities desired
  36. Return Value:
  37. the appropriate capabilities
  38. --*/
  39. {
  40. DWORD rc = 0;
  41. DbgP(( L"GetNetCaps .....\n" ));
  42. switch ( nIndex )
  43. {
  44. case WNNC_SPEC_VERSION:
  45. rc = WNNC_SPEC_VERSION51;
  46. break;
  47. case WNNC_NET_TYPE:
  48. rc = WNNC_NET_RDR2SAMPLE;
  49. break;
  50. case WNNC_DRIVER_VERSION:
  51. rc = WNNC_DRIVER(1, 0);
  52. break;
  53. case WNNC_CONNECTION:
  54. rc = WNNC_CON_GETCONNECTIONS |
  55. WNNC_CON_CANCELCONNECTION |
  56. WNNC_CON_ADDCONNECTION |
  57. WNNC_CON_ADDCONNECTION3;
  58. break;
  59. case WNNC_ENUMERATION:
  60. rc = WNNC_ENUM_LOCAL;
  61. break;
  62. case WNNC_START:
  63. rc = 1;
  64. break;
  65. case WNNC_USER:
  66. case WNNC_DIALOG:
  67. case WNNC_ADMIN:
  68. default:
  69. rc = 0;
  70. break;
  71. }
  72. return rc;
  73. }
  74. DWORD APIENTRY
  75. NPLogonNotify(
  76. PLUID lpLogonId,
  77. LPCWSTR lpAuthentInfoType,
  78. LPVOID lpAuthentInfo,
  79. LPCWSTR lpPreviousAuthentInfoType,
  80. LPVOID lpPreviousAuthentInfo,
  81. LPWSTR lpStationName,
  82. LPVOID StationHandle,
  83. LPWSTR *lpLogonScript)
  84. /*++
  85. Routine Description:
  86. This routine handles the logon notifications
  87. Arguments:
  88. lpLogonId -- the associated LUID
  89. lpAuthenInfoType - the authentication information type
  90. lpAuthenInfo - the authentication Information
  91. lpPreviousAuthentInfoType - the previous aunthentication information type
  92. lpPreviousAuthentInfo - the previous authentication information
  93. lpStationName - the logon station name
  94. LPVOID - logon station handle
  95. lpLogonScript - the logon script to be executed.
  96. Return Value:
  97. WN_SUCCESS
  98. Notes:
  99. This capability has not been implemented in the sample.
  100. --*/
  101. {
  102. *lpLogonScript = NULL;
  103. return WN_SUCCESS;
  104. }
  105. DWORD APIENTRY
  106. NPPasswordChangeNotify (
  107. LPCWSTR lpAuthentInfoType,
  108. LPVOID lpAuthentInfo,
  109. LPCWSTR lpPreviousAuthentInfoType,
  110. LPVOID lpPreviousAuthentInfo,
  111. LPWSTR lpStationName,
  112. LPVOID StationHandle,
  113. DWORD dwChangeInfo )
  114. /*++
  115. Routine Description:
  116. This routine handles the password change notifications
  117. Arguments:
  118. lpAuthenInfoType - the authentication information type
  119. lpAuthenInfo - the authentication Information
  120. lpPreviousAuthentInfoType - the previous aunthentication information type
  121. lpPreviousAuthentInfo - the previous authentication information
  122. lpStationName - the logon station name
  123. LPVOID - logon station handle
  124. dwChangeInfo - the password change information.
  125. Return Value:
  126. WN_NOT_SUPPORTED
  127. Notes:
  128. This capability has not been implemented in the sample.
  129. --*/
  130. {
  131. SetLastError( WN_NOT_SUPPORTED );
  132. return WN_NOT_SUPPORTED;
  133. }
  134. ULONG
  135. SendToMiniRdr(
  136. IN ULONG IoctlCode,
  137. IN PVOID InputDataBuf,
  138. IN ULONG InputDataLen,
  139. IN PVOID OutputDataBuf,
  140. IN PULONG pOutputDataLen)
  141. /*++
  142. Routine Description:
  143. This routine sends a device ioctl to the Mini Rdr.
  144. Arguments:
  145. IoctlCode - Function code for the Mini Rdr driver
  146. InputDataBuf - Input buffer pointer
  147. InputDataLen - Lenth of the input buffer
  148. OutputDataBuf - Output buffer pointer
  149. pOutputDataLen - Pointer to the length of the output buffer
  150. Return Value:
  151. WN_SUCCESS if successful, otherwise the appropriate error
  152. Notes:
  153. --*/
  154. {
  155. HANDLE DeviceHandle; // The mini rdr device handle
  156. ULONG BytesRet;
  157. BOOL rc;
  158. ULONG Status;
  159. Status = WN_SUCCESS;
  160. // Grab a handle to the redirector device object
  161. DeviceHandle = CreateFile(
  162. DD_NULMRX_USERMODE_DEV_NAME_U,
  163. GENERIC_READ | GENERIC_WRITE,
  164. FILE_SHARE_READ | FILE_SHARE_WRITE,
  165. (LPSECURITY_ATTRIBUTES)NULL,
  166. OPEN_EXISTING,
  167. 0,
  168. (HANDLE) NULL );
  169. if ( INVALID_HANDLE_VALUE != DeviceHandle )
  170. {
  171. rc = DeviceIoControl(
  172. DeviceHandle,
  173. IoctlCode,
  174. InputDataBuf,
  175. InputDataLen,
  176. OutputDataBuf,
  177. *pOutputDataLen,
  178. pOutputDataLen,
  179. NULL );
  180. if ( !rc )
  181. {
  182. DbgP(( L"SendToMiniRdr: returning error from DeviceIoctl\n" ));
  183. Status = GetLastError( );
  184. }
  185. else
  186. {
  187. DbgP(( L"SendToMiniRdr: The DeviceIoctl call succeded\n" ));
  188. }
  189. CloseHandle(DeviceHandle);
  190. }
  191. else
  192. {
  193. Status = GetLastError( );
  194. DbgP(( L"SendToMiniRdr: error %lx opening device \n", Status ));
  195. }
  196. return Status;
  197. }
  198. DWORD APIENTRY
  199. NPAddConnection(
  200. LPNETRESOURCE lpNetResource,
  201. LPWSTR lpPassword,
  202. LPWSTR lpUserName )
  203. /*++
  204. Routine Description:
  205. This routine adds a connection to the list of connections associated
  206. with this network provider
  207. Arguments:
  208. lpNetResource - the NETRESOURCE struct
  209. lpPassword - the password
  210. lpUserName - the user name
  211. Return Value:
  212. WN_SUCCESS if successful, otherwise the appropriate error
  213. Notes:
  214. --*/
  215. {
  216. DbgP(( L"NPAddConnection....\n" ));
  217. return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
  218. }
  219. DWORD APIENTRY
  220. NPAddConnection3(
  221. HWND hwndOwner,
  222. LPNETRESOURCE lpNetResource,
  223. LPWSTR lpPassword,
  224. LPWSTR lpUserName,
  225. DWORD dwFlags )
  226. /*++
  227. Routine Description:
  228. This routine adds a connection to the list of connections associated
  229. with this network provider
  230. Arguments:
  231. hwndOwner - the owner handle
  232. lpNetResource - the NETRESOURCE struct
  233. lpPassword - the password
  234. lpUserName - the user name
  235. dwFlags - flags for the connection
  236. Return Value:
  237. WN_SUCCESS if successful, otherwise the appropriate error
  238. --*/
  239. {
  240. DWORD Status;
  241. WCHAR ConnectionName[128];
  242. WCHAR wszScratch[128];
  243. WCHAR LocalName[3];
  244. DWORD CopyBytes = 0;
  245. DbgP(( L"NPAddConnection3....\n" ));
  246. DbgP(( L"Local Name: %s\n", lpNetResource->lpLocalName ));
  247. DbgP(( L"Remote Name: %s\n", lpNetResource->lpRemoteName ));
  248. Status = WN_SUCCESS;
  249. // \device\miniredirector\;<DriveLetter>:\Server\Share
  250. if ( lstrlen( lpNetResource->lpLocalName ) > 1 )
  251. {
  252. if ( lpNetResource->lpLocalName[1] == L':' )
  253. {
  254. // LocalName[0] = (WCHAR) CharUpper( (PWCHAR) MAKELONG( (USHORT) lpNetResource->lpLocalName[0], 0 ) );
  255. LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]);
  256. LocalName[1] = L':';
  257. LocalName[2] = L'\0';
  258. lstrcpyn( ConnectionName, DD_NULMRX_FS_DEVICE_NAME_U, 126 );
  259. wcsncat(ConnectionName, L"\\;", 3 );
  260. wcsncat(ConnectionName, LocalName, 128-wcslen(ConnectionName));
  261. }
  262. else
  263. {
  264. Status = WN_BAD_LOCALNAME;
  265. }
  266. }
  267. else
  268. {
  269. Status = WN_BAD_LOCALNAME;
  270. }
  271. if (Status == WN_SUCCESS)
  272. {
  273. if(lpNetResource->lpRemoteName[0] == L'\0')
  274. {
  275. Status = WN_BAD_NETNAME;
  276. }
  277. // format proper server name
  278. else if ( lpNetResource->lpRemoteName[0] == L'\\' && lpNetResource->lpRemoteName[1] == L'\\' )
  279. {
  280. wcsncat( ConnectionName, lpNetResource->lpRemoteName + 1 , 128-wcslen(ConnectionName));
  281. DbgP(( L"Full Connect Name: %s\n", ConnectionName ));
  282. DbgP(( L"Full Connect Name Length: %d\n", ( wcslen( ConnectionName ) + 1 ) * sizeof( WCHAR ) ));
  283. }
  284. else
  285. {
  286. Status = WN_BAD_NETNAME;
  287. }
  288. }
  289. if ( Status == WN_SUCCESS )
  290. {
  291. if ( QueryDosDevice( LocalName, wszScratch, 128 ) )
  292. {
  293. Status = WN_ALREADY_CONNECTED;
  294. }
  295. else if ( GetLastError( ) == ERROR_FILE_NOT_FOUND )
  296. {
  297. HANDLE hFile;
  298. Status = SendToMiniRdr( IOCTL_NULMRX_ADDCONN, ConnectionName,
  299. ( lstrlen( ConnectionName ) + 1 ) * sizeof( WCHAR ),
  300. NULL, &CopyBytes );
  301. if ( Status == WN_SUCCESS )
  302. {
  303. if ( !DefineDosDevice( DDD_RAW_TARGET_PATH |
  304. DDD_NO_BROADCAST_SYSTEM,
  305. lpNetResource->lpLocalName,
  306. ConnectionName ) )
  307. {
  308. Status = GetLastError( );
  309. }
  310. }
  311. else
  312. {
  313. Status = WN_BAD_NETNAME;
  314. }
  315. }
  316. else
  317. {
  318. Status = WN_ALREADY_CONNECTED;
  319. }
  320. }
  321. return Status;
  322. }
  323. DWORD APIENTRY
  324. NPCancelConnection(
  325. LPWSTR lpName,
  326. BOOL fForce )
  327. /*++
  328. Routine Description:
  329. This routine cancels ( deletes ) a connection from the list of connections
  330. associated with this network provider
  331. Arguments:
  332. lpName - name of the connection
  333. fForce - forcefully delete the connection
  334. Return Value:
  335. WN_SUCCESS if successful, otherwise the appropriate error
  336. Notes:
  337. --*/
  338. {
  339. WCHAR LocalName[3];
  340. WCHAR RemoteName[128];
  341. WCHAR ConnectionName[128];
  342. ULONG CopyBytes;
  343. DWORD DisconnectResult;
  344. DWORD Status = WN_NOT_CONNECTED;
  345. if(lpName == NULL)
  346. return Status;
  347. if ( lstrlen( lpName ) > 1 )
  348. {
  349. if ( lpName[1] == L':' )
  350. {
  351. // LocalName[0] = (WCHAR) CharUpper( (PWCHAR) MAKELONG( (USHORT) lpName[0], 0 ) );
  352. LocalName[0] = (WCHAR) toupper(lpName[0]);
  353. LocalName[1] = L':';
  354. LocalName[2] = L'\0';
  355. CopyBytes = 128 * sizeof(WCHAR);
  356. Status = SendToMiniRdr( IOCTL_NULMRX_GETCONN, LocalName, 3 * sizeof( WCHAR ),
  357. (PVOID) RemoteName, &CopyBytes );
  358. if ( Status == WN_SUCCESS && CopyBytes > 0 && CopyBytes < 128 * sizeof(WCHAR) )
  359. {
  360. RemoteName[CopyBytes/sizeof(WCHAR)] = L'\0';
  361. lstrcpyn( ConnectionName, DD_NULMRX_FS_DEVICE_NAME_U, 126 );
  362. wcsncat( ConnectionName, L"\\;", 3);
  363. wcsncat( ConnectionName, LocalName, 128-wcslen(ConnectionName) );
  364. wcsncat( ConnectionName, RemoteName, 128-wcslen(ConnectionName) );
  365. ConnectionName[127] = L'\0';
  366. CopyBytes = 0;
  367. Status = SendToMiniRdr( IOCTL_NULMRX_DELCONN, ConnectionName,
  368. ( wcslen( ConnectionName ) + 1 ) * sizeof( WCHAR ),
  369. NULL, &CopyBytes );
  370. if ( Status == WN_SUCCESS )
  371. {
  372. if ( !DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
  373. LocalName,
  374. ConnectionName ) )
  375. {
  376. Status = GetLastError( );
  377. }
  378. }
  379. }
  380. else
  381. {
  382. Status = WN_NOT_CONNECTED;
  383. }
  384. }
  385. }
  386. return Status;
  387. }
  388. DWORD APIENTRY
  389. NPGetConnection(
  390. LPWSTR lpLocalName,
  391. LPWSTR lpRemoteName,
  392. LPDWORD lpBufferSize )
  393. /*++
  394. Routine Description:
  395. This routine returns the information associated with a connection
  396. Arguments:
  397. lpLocalName - local name associated with the connection
  398. lpRemoteName - the remote name associated with the connection
  399. lpBufferSize - the remote name buffer size
  400. Return Value:
  401. WN_SUCCESS if successful, otherwise the appropriate error
  402. Notes:
  403. --*/
  404. {
  405. DWORD Status, len, i;
  406. ULONG CopyBytes;
  407. WCHAR RemoteName[128];
  408. WCHAR LocalName[3];
  409. Status = WN_NOT_CONNECTED;
  410. DbgP(( L"NPGetConnection....\n" ));
  411. if(lpLocalName == NULL)
  412. return Status;
  413. if ( wcslen( lpLocalName ) > 1 )
  414. {
  415. if ( lpLocalName[1] == L':' )
  416. {
  417. CopyBytes = 128*sizeof(WCHAR);
  418. // LocalName[0] = (WCHAR) CharUpper( (PWCHAR) MAKELONG( (USHORT) lpLocalName[0], 0 ) );
  419. LocalName[0] = (WCHAR) toupper(lpLocalName[0]);
  420. LocalName[1] = L':';
  421. LocalName[2] = L'\0';
  422. Status = SendToMiniRdr( IOCTL_NULMRX_GETCONN, LocalName, 3 * sizeof( WCHAR ),
  423. (PVOID) RemoteName, &CopyBytes );
  424. }
  425. }
  426. if ( Status == WN_SUCCESS )
  427. {
  428. len = CopyBytes + sizeof(WCHAR);
  429. if ( *lpBufferSize > len )
  430. {
  431. *lpRemoteName++ = L'\\';
  432. CopyMemory( lpRemoteName, RemoteName, CopyBytes );
  433. lpRemoteName[CopyBytes/sizeof(WCHAR)] = L'\0';
  434. }
  435. else
  436. {
  437. Status = WN_MORE_DATA;
  438. *lpBufferSize = len;
  439. }
  440. }
  441. return Status;
  442. }
  443. DWORD APIENTRY
  444. NPOpenEnum(
  445. DWORD dwScope,
  446. DWORD dwType,
  447. DWORD dwUsage,
  448. LPNETRESOURCE lpNetResource,
  449. LPHANDLE lphEnum )
  450. /*++
  451. Routine Description:
  452. This routine opens a handle for enumeration of resources. The only capability
  453. implemented in the sample is for enumerating connected shares
  454. Arguments:
  455. dwScope - the scope of enumeration
  456. dwType - the type of resources to be enumerated
  457. dwUsage - the usage parameter
  458. lpNetResource - a pointer to the desired NETRESOURCE struct.
  459. lphEnum - aptr. for passing nack the enumeration handle
  460. Return Value:
  461. WN_SUCCESS if successful, otherwise the appropriate error
  462. Notes:
  463. The sample only supports the notion of enumerating connected shares
  464. The handle passed back is merely the index of the last entry returned
  465. --*/
  466. {
  467. DWORD Status;
  468. DbgP((L"NPOpenEnum\n"));
  469. *lphEnum = NULL;
  470. switch ( dwScope )
  471. {
  472. case RESOURCE_CONNECTED:
  473. {
  474. *lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( ULONG ) );
  475. if (*lphEnum )
  476. {
  477. Status = WN_SUCCESS;
  478. }
  479. else
  480. {
  481. Status = WN_OUT_OF_MEMORY;
  482. }
  483. break;
  484. }
  485. break;
  486. case RESOURCE_CONTEXT:
  487. default:
  488. Status = WN_NOT_SUPPORTED;
  489. break;
  490. }
  491. DbgP((L"NPOpenEnum returning Status %lx\n",Status));
  492. return(Status);
  493. }
  494. DWORD APIENTRY
  495. NPEnumResource(
  496. HANDLE hEnum,
  497. LPDWORD lpcCount,
  498. LPVOID lpBuffer,
  499. LPDWORD lpBufferSize)
  500. /*++
  501. Routine Description:
  502. This routine uses the handle obtained by a call to NPOpenEnum for
  503. enuerating the connected shares
  504. Arguments:
  505. hEnum - the enumeration handle
  506. lpcCount - the number of resources returned
  507. lpBuffer - the buffere for passing back the entries
  508. lpBufferSize - the size of the buffer
  509. Return Value:
  510. WN_SUCCESS if successful, otherwise the appropriate error
  511. WN_NO_MORE_ENTRIES - if the enumeration has exhausted the entries
  512. WN_MORE_DATA - if nmore data is available
  513. Notes:
  514. The sample only supports the notion of enumerating connected shares
  515. The handle passed back is merely the index of the last entry returned
  516. --*/
  517. {
  518. DWORD Status = WN_SUCCESS;
  519. BYTE ConnectionList[26];
  520. ULONG CopyBytes;
  521. ULONG EntriesCopied;
  522. ULONG i;
  523. LPNETRESOURCE pNetResource;
  524. ULONG SpaceNeeded;
  525. ULONG SpaceAvailable;
  526. WCHAR LocalName[3];
  527. WCHAR RemoteName[128];
  528. PWCHAR StringZone;
  529. DbgP((L"NPEnumResource\n"));
  530. DbgP((L"NPEnumResource Count Requested %d\n", *lpcCount));
  531. pNetResource = (LPNETRESOURCE) lpBuffer;
  532. SpaceAvailable = *lpBufferSize;
  533. EntriesCopied = 0;
  534. StringZone = (PWCHAR) ((PBYTE)lpBuffer + *lpBufferSize);
  535. CopyBytes = 26;
  536. Status = SendToMiniRdr( IOCTL_NULMRX_GETLIST, NULL, 0,
  537. (PVOID) ConnectionList, &CopyBytes );
  538. i = *((PULONG)hEnum);
  539. if ( Status == WN_SUCCESS)
  540. {
  541. for ( i = *((PULONG) hEnum); EntriesCopied < *lpcCount && i < 26; i++ )
  542. {
  543. if ( ConnectionList[i] )
  544. {
  545. CopyBytes = 128*sizeof(WCHAR);
  546. LocalName[0] = L'A' + (WCHAR) i;
  547. LocalName[1] = L':';
  548. LocalName[2] = L'\0';
  549. Status = SendToMiniRdr( IOCTL_NULMRX_GETCONN, LocalName, 3 * sizeof(WCHAR),
  550. (PVOID) RemoteName, &CopyBytes );
  551. // if something strange happended then just say there are no more entries
  552. if ( Status != WN_SUCCESS || CopyBytes == 0 )
  553. {
  554. Status = WN_NO_MORE_ENTRIES;
  555. break;
  556. }
  557. // Determine the space needed for this entry...
  558. SpaceNeeded = sizeof( NETRESOURCE ); // resource struct
  559. SpaceNeeded += 3 * sizeof(WCHAR); // local name
  560. SpaceNeeded += 2 * sizeof(WCHAR) + CopyBytes; // remote name
  561. SpaceNeeded += 5 * sizeof(WCHAR); // comment
  562. SpaceNeeded += sizeof(NULMRX_PROVIDER_NAME_U); // provider name
  563. if ( SpaceNeeded > SpaceAvailable )
  564. {
  565. break;
  566. }
  567. else
  568. {
  569. SpaceAvailable -= SpaceNeeded;
  570. pNetResource->dwScope = RESOURCE_CONNECTED;
  571. pNetResource->dwType = RESOURCETYPE_DISK;
  572. pNetResource->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
  573. pNetResource->dwUsage = 0;
  574. // setup string area at opposite end of buffer
  575. SpaceNeeded -= sizeof( NETRESOURCE );
  576. StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
  577. // copy local name
  578. pNetResource->lpLocalName = StringZone;
  579. *StringZone++ = L'A' + (WCHAR) i;
  580. *StringZone++ = L':';
  581. *StringZone++ = L'\0';
  582. // copy remote name
  583. pNetResource->lpRemoteName = StringZone;
  584. *StringZone++ = L'\\';
  585. CopyMemory( StringZone, RemoteName, CopyBytes );
  586. StringZone += CopyBytes / sizeof(WCHAR);
  587. *StringZone++ = L'\0';
  588. // copy comment
  589. pNetResource->lpComment = StringZone;
  590. *StringZone++ = L'A';
  591. *StringZone++ = L'_';
  592. *StringZone++ = L'O';
  593. *StringZone++ = L'K';
  594. *StringZone++ = L'\0';
  595. // copy provider name
  596. pNetResource->lpProvider = StringZone;
  597. lstrcpyn( StringZone, NULMRX_PROVIDER_NAME_U, sizeof(NULMRX_PROVIDER_NAME_U)/sizeof(WCHAR) );
  598. EntriesCopied++;
  599. // set new bottom of string zone
  600. StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
  601. }
  602. pNetResource++;
  603. }
  604. }
  605. }
  606. else
  607. {
  608. Status = WN_NO_MORE_ENTRIES;
  609. }
  610. *lpcCount = EntriesCopied;
  611. if ( EntriesCopied == 0 && Status == WN_SUCCESS )
  612. {
  613. if ( i > 25 )
  614. {
  615. Status = WN_NO_MORE_ENTRIES;
  616. }
  617. else
  618. {
  619. DbgP((L"NPEnumResource More Data Needed - %d\n", SpaceNeeded));
  620. Status = WN_MORE_DATA;
  621. *lpBufferSize = SpaceNeeded;
  622. }
  623. }
  624. // update entry index
  625. *(PULONG) hEnum = i;
  626. DbgP((L"NPEnumResource Entries returned - %d\n", EntriesCopied));
  627. return Status;
  628. }
  629. DWORD APIENTRY
  630. NPCloseEnum(
  631. HANDLE hEnum )
  632. /*++
  633. Routine Description:
  634. This routine closes the handle for enumeration of resources.
  635. Arguments:
  636. hEnum - the enumeration handle
  637. Return Value:
  638. WN_SUCCESS if successful, otherwise the appropriate error
  639. Notes:
  640. The sample only supports the notion of enumerating connected shares
  641. --*/
  642. {
  643. DbgP((L"NPCloseEnum\n"));
  644. HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
  645. return WN_SUCCESS;
  646. }
  647. DWORD APIENTRY
  648. NPGetResourceParent(
  649. LPNETRESOURCE lpNetResource,
  650. LPVOID lpBuffer,
  651. LPDWORD lpBufferSize )
  652. /*++
  653. Routine Description:
  654. This routine returns the information about net resource parent
  655. Arguments:
  656. lpNetResource - the NETRESOURCE struct
  657. lpBuffer - the buffer for passing back the parent information
  658. lpBufferSize - the buffer size
  659. Return Value:
  660. Notes:
  661. --*/
  662. {
  663. DbgP(( L"NPGetResourceParent: WN_NOT_SUPPORTED\n" ));
  664. return WN_NOT_SUPPORTED;
  665. }
  666. DWORD APIENTRY
  667. NPGetResourceInformation(
  668. LPNETRESOURCE lpNetResource,
  669. LPVOID lpBuffer,
  670. LPDWORD lpBufferSize,
  671. LPWSTR *lplpSystem )
  672. /*++
  673. Routine Description:
  674. This routine returns the information associated net resource
  675. Arguments:
  676. lpNetResource - the NETRESOURCE struct
  677. lpBuffer - the buffer for passing back the parent information
  678. lpBufferSize - the buffer size
  679. lplpSystem -
  680. Return Value:
  681. Notes:
  682. --*/
  683. {
  684. DbgP(( L"NPGetResourceInformation: WN_NOT_SUPPORTED\n" ));
  685. return WN_NOT_SUPPORTED;
  686. }
  687. DWORD APIENTRY
  688. NPGetUniversalName(
  689. LPCWSTR lpLocalPath,
  690. DWORD dwInfoLevel,
  691. LPVOID lpBuffer,
  692. LPDWORD lpBufferSize )
  693. /*++
  694. Routine Description:
  695. This routine returns the information associated net resource
  696. Arguments:
  697. lpLocalPath - the local path name
  698. dwInfoLevel - the desired info level
  699. lpBuffer - the buffer for the univeral name
  700. lpBufferSize - the buffer size
  701. Return Value:
  702. WN_SUCCESS if successful
  703. Notes:
  704. --*/
  705. {
  706. DbgP(( L"NPGetUniversalName: WN_NOT_SUPPORTED\n" ));
  707. return WN_NOT_SUPPORTED;
  708. }
  709. int _cdecl _vsnwprintf( wchar_t *buffer, size_t count, wchar_t *format, va_list arg_ptr);
  710. // Format and write debug information to OutputDebugString
  711. ULONG _cdecl WideDbgPrint( LPTSTR Format, ... )
  712. {
  713. ULONG rc = 0;
  714. TCHAR szbuffer[256];
  715. va_list marker;
  716. va_start( marker, Format );
  717. {
  718. rc = _vsnwprintf( szbuffer, 254, Format, marker );
  719. szbuffer[255] = (TCHAR)0;
  720. OutputDebugString( TRACE_TAG );
  721. OutputDebugString( szbuffer );
  722. }
  723. return rc;
  724. }