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.

621 lines
14 KiB

  1. /*************************************************************************
  2. *
  3. * NT.C
  4. *
  5. * NT NetWare routines
  6. *
  7. * Copyright (c) 1995 Microsoft Corporation
  8. *
  9. * $Log: N:\NT\PRIVATE\NW4\NWSCRIPT\VCS\NT.C $
  10. *
  11. * Rev 1.4 22 Dec 1995 14:25:12 terryt
  12. * Add Microsoft headers
  13. *
  14. * Rev 1.3 28 Nov 1995 17:13:28 terryt
  15. * Cleanup resource file
  16. *
  17. * Rev 1.2 22 Nov 1995 15:43:44 terryt
  18. * Use proper NetWare user name call
  19. *
  20. * Rev 1.1 20 Nov 1995 16:10:00 terryt
  21. * Close open NDS handles
  22. *
  23. * Rev 1.0 15 Nov 1995 18:07:18 terryt
  24. * Initial revision.
  25. *
  26. * Rev 1.2 25 Aug 1995 16:23:02 terryt
  27. * Capture support
  28. *
  29. * Rev 1.1 23 May 1995 19:37:02 terryt
  30. * Spruce up source
  31. *
  32. * Rev 1.0 15 May 1995 19:10:40 terryt
  33. * Initial revision.
  34. *
  35. *************************************************************************/
  36. #include <common.h>
  37. #include <nwapi.h>
  38. #include <npapi.h>
  39. #include "ntnw.h"
  40. /*
  41. * Name of NetWare provider
  42. */
  43. TCHAR NW_PROVIDER[60];
  44. unsigned char NW_PROVIDERA[60];
  45. /********************************************************************
  46. NTPrintExtendedError
  47. Routine Description:
  48. Print any extended errors from WNet routines
  49. Arguments:
  50. None
  51. Return Value:
  52. None
  53. *******************************************************************/
  54. void
  55. NTPrintExtendedError( void )
  56. {
  57. DWORD ExError;
  58. wchar_t provider[32];
  59. wchar_t description[1024];
  60. if ( !WNetGetLastErrorW( &ExError, description, 1024, provider, 32 ) )
  61. wprintf(L"%s\n", description);
  62. }
  63. /********************************************************************
  64. NTInitProvider
  65. Routine Description:
  66. Retrieve provider name and save old paths
  67. Arguments:
  68. None
  69. Return Value:
  70. None
  71. *******************************************************************/
  72. void
  73. NTInitProvider( void )
  74. {
  75. HKEY hKey;
  76. DWORD dwType, dwSize;
  77. LONG Status;
  78. BOOL ret = FALSE;
  79. dwSize = sizeof(NW_PROVIDER);
  80. if ((Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_PROVIDER, 0, KEY_READ, &hKey)) == ERROR_SUCCESS) {
  81. (void) RegQueryValueEx(hKey, REGISTRY_PROVIDERNAME, NULL, &dwType, (LPBYTE) NW_PROVIDER, &dwSize);
  82. WideTosz( NW_PROVIDERA, NW_PROVIDER, sizeof(NW_PROVIDERA) );
  83. RegCloseKey(hKey);
  84. }
  85. GetOldPaths();
  86. }
  87. /********************************************************************
  88. DeleteDriveBase
  89. Routine Description:
  90. Disconnect drive from network
  91. Arguments:
  92. DriveNumber - number of drive 1-26
  93. Return Value:
  94. 0 - success
  95. else NetWare error
  96. *******************************************************************/
  97. unsigned int
  98. DeleteDriveBase( unsigned short DriveNumber)
  99. {
  100. static char drivename[] = "A:";
  101. unsigned int dwRes;
  102. drivename[0] = 'A' + DriveNumber - 1;
  103. dwRes = WNetCancelConnection2A( drivename, 0, TRUE );
  104. if ( dwRes != NO_ERROR )
  105. dwRes = GetLastError();
  106. if ( dwRes == ERROR_EXTENDED_ERROR )
  107. NTPrintExtendedError();
  108. return dwRes;
  109. }
  110. /********************************************************************
  111. DetachFromFileServer
  112. Routine Description:
  113. Break connection from a file server
  114. Arguments:
  115. ConnectionId - Connection handle
  116. Return Value:
  117. 0 = success
  118. else NT error
  119. *******************************************************************/
  120. unsigned int
  121. DetachFromFileServer( unsigned int ConnectionId )
  122. {
  123. return ( NWDetachFromFileServer( (NWCONN_HANDLE)ConnectionId ) );
  124. }
  125. /********************************************************************
  126. NTLoginToFileServer
  127. Routine Description:
  128. Login to a file server given a user name and password.
  129. If a NULL password is passed in, the default password should
  130. be tried if no password failed.
  131. Arguments:
  132. pszServerName - Server name
  133. pszUserName - User name
  134. pszPassword - Password
  135. Return Value:
  136. 0 = success
  137. else NetWare error
  138. *******************************************************************/
  139. unsigned int
  140. NTLoginToFileServer(
  141. char *pszServerName,
  142. char *pszUserName,
  143. char *pszPassword
  144. )
  145. {
  146. NETRESOURCEA NetResource;
  147. DWORD dwRes;
  148. //
  149. // validate parameters
  150. //
  151. if (!pszServerName || !pszUserName || !pszPassword) {
  152. DisplayMessage(IDR_ERROR_DURING, "NTLoginToFileServer");
  153. return 0xffffffff ;
  154. }
  155. NetResource.dwScope = 0 ;
  156. NetResource.dwUsage = 0 ;
  157. NetResource.dwType = RESOURCETYPE_ANY;
  158. NetResource.lpLocalName = NULL;
  159. NetResource.lpRemoteName = pszServerName;
  160. NetResource.lpComment = NULL;
  161. // NetResource.lpProvider = NW_PROVIDERA ;
  162. // Allow OS to select provider in case localized name doesn't map to OEM code page
  163. NetResource.lpProvider = NULL;
  164. //
  165. // make the connection
  166. //
  167. dwRes=WNetAddConnection2A ( &NetResource,
  168. pszPassword,
  169. pszUserName,
  170. 0 );
  171. if ( dwRes != NO_ERROR )
  172. dwRes = GetLastError();
  173. //
  174. // Try default password if no password was specified
  175. //
  176. // The error numbers aren't (or weren't) reliable (ERROR_INVALID_PASSWORD)
  177. //
  178. if ( ( dwRes != NO_ERROR ) && ( pszPassword[0] == '\0' ) ) {
  179. dwRes=WNetAddConnection2A ( &NetResource,
  180. NULL,
  181. pszUserName,
  182. 0 );
  183. if ( dwRes != NO_ERROR )
  184. dwRes = GetLastError();
  185. }
  186. return( dwRes );
  187. }
  188. /********************************************************************
  189. GetFileServerName
  190. Routine Description:
  191. Return the server name associated with the connection ID
  192. Arguments:
  193. ConnectionId - Connection ID to a server
  194. pServerName - Returned server name
  195. Return Value:
  196. 0 - success
  197. else NT error
  198. *******************************************************************/
  199. unsigned int
  200. GetFileServerName(
  201. unsigned int ConnectionId,
  202. char * pServerName
  203. )
  204. {
  205. unsigned int Result;
  206. VERSION_INFO VerInfo;
  207. *pServerName = '\0';
  208. Result = NWGetFileServerVersionInfo( (NWCONN_HANDLE) ConnectionId,
  209. &VerInfo );
  210. if ( !Result )
  211. {
  212. strcpy( pServerName, VerInfo.szName );
  213. }
  214. return Result;
  215. }
  216. /********************************************************************
  217. SetDriveBase
  218. Routine Description:
  219. Connect a drive to a NetWare volume
  220. Arguments:
  221. DriveNumber - number of drive 1-26
  222. ServerName - server name
  223. DirHandle - not used
  224. pDirPath - Volume:\Path
  225. Return Value:
  226. 0 = success
  227. else NetWare error
  228. *******************************************************************/
  229. unsigned int
  230. SetDriveBase(
  231. unsigned short DriveNumber,
  232. unsigned char *ServerName,
  233. unsigned int DirHandle,
  234. unsigned char *pDirPath
  235. )
  236. {
  237. unsigned int Result = 0;
  238. static char driveName[] = "A:" ;
  239. /*
  240. * DirHandle is never used
  241. */
  242. driveName[0]= 'A' + DriveNumber - 1;
  243. if ( ( ServerName[0] == '\0' ) && fNDS ) {
  244. /*
  245. * Assume its an NDS volume name, if that fails, then
  246. * try a default file server volume.
  247. */
  248. Result = NTSetDriveBase( driveName, NDSTREE, pDirPath );
  249. if ( !Result )
  250. return Result;
  251. Result = NTSetDriveBase( driveName, PREFERRED_SERVER, pDirPath );
  252. return Result;
  253. }
  254. Result = NTSetDriveBase( driveName, ServerName, pDirPath );
  255. return Result;
  256. }
  257. /********************************************************************
  258. NTSetDriveBase
  259. Routine Description:
  260. Connect a local name to a NetWare volume and path
  261. Arguments:
  262. pszLocalName - local name to connect
  263. pszServerName - name of file server
  264. pszDirPath - Volume:\Path
  265. Return Value:
  266. 0 = success
  267. else NetWare error
  268. *******************************************************************/
  269. unsigned int
  270. NTSetDriveBase( unsigned char * pszLocalName,
  271. unsigned char * pszServerName,
  272. unsigned char * pszDirPath )
  273. {
  274. NETRESOURCEA NetResource;
  275. DWORD dwRes, dwSize;
  276. unsigned char * pszRemoteName = NULL;
  277. char * p;
  278. //
  279. // validate parameters
  280. //
  281. if (!pszLocalName || !pszServerName || !pszDirPath) {
  282. DisplayMessage(IDR_ERROR_DURING, "NTSetDriveBase");
  283. return 0xffffffff ;
  284. }
  285. //
  286. // allocate memory for string
  287. //
  288. dwSize = strlen(pszDirPath) + strlen(pszServerName) + 5 ;
  289. if (!(pszRemoteName = (unsigned char *)LocalAlloc(
  290. LPTR,
  291. dwSize)))
  292. {
  293. DisplayMessage(IDR_NOT_ENOUGH_MEMORY);
  294. dwRes = 0xffffffff;
  295. goto ExitPoint ;
  296. }
  297. //
  298. // The requester understands
  299. // server\volume:dir
  300. // but not
  301. // server\volume:\dir
  302. //
  303. // So just convert it to UNC
  304. //
  305. strcpy( pszRemoteName, "\\\\" );
  306. strcat( pszRemoteName, pszServerName );
  307. strcat( pszRemoteName, "\\" );
  308. strcat( pszRemoteName, pszDirPath );
  309. p = strchr( pszRemoteName, ':' );
  310. if ( !p ) {
  311. DisplayMessage(IDR_NO_VOLUME);
  312. dwRes = 0xffffffff;
  313. goto ExitPoint ;
  314. }
  315. *p++ = '\\';
  316. if ( *p == '\\' ) {
  317. /* Don't want a double backslash */
  318. *p = '\0';
  319. p = strchr( pszDirPath, ':' );
  320. p++;
  321. p++;
  322. strcat( pszRemoteName, p );
  323. }
  324. //
  325. // strip off trailing backslash
  326. //
  327. if (pszRemoteName[strlen(pszRemoteName)-1] == '\\')
  328. pszRemoteName[strlen(pszRemoteName)-1] = '\0';
  329. NetResource.dwScope = 0 ;
  330. NetResource.dwUsage = 0 ;
  331. NetResource.dwType = RESOURCETYPE_DISK;
  332. NetResource.lpLocalName = pszLocalName;
  333. NetResource.lpRemoteName = pszRemoteName;
  334. NetResource.lpComment = NULL;
  335. // NetResource.lpProvider = NW_PROVIDERA ;
  336. // Allow OS to select provider in case localized name doesn't map to OEM code page
  337. NetResource.lpProvider = NULL;
  338. //
  339. // make the connection
  340. //
  341. dwRes=WNetAddConnection2A ( &NetResource, NULL, NULL, 0 );
  342. if ( dwRes != NO_ERROR )
  343. dwRes = GetLastError();
  344. ExitPoint:
  345. if (pszRemoteName)
  346. (void) LocalFree((HLOCAL) pszRemoteName) ;
  347. return( dwRes );
  348. }
  349. /********************************************************************
  350. Is40Server
  351. Routine Description:
  352. Returns TRUE if 4X server
  353. Arguments:
  354. ConnectionHandle - Connection Handle
  355. Return Value:
  356. TRUE = 4X server
  357. FALSE = pre-4X server
  358. *******************************************************************/
  359. unsigned int
  360. Is40Server(
  361. unsigned int ConnectionHandle
  362. )
  363. {
  364. NTSTATUS NtStatus ;
  365. VERSION_INFO VerInfo;
  366. unsigned int Version;
  367. NtStatus = NWGetFileServerVersionInfo( (NWCONN_HANDLE)ConnectionHandle,
  368. &VerInfo );
  369. if (!NT_SUCCESS(NtStatus))
  370. FALSE;
  371. Version = VerInfo.Version * 1000 + VerInfo.SubVersion * 10;
  372. if ( Version >= 4000 ) {
  373. return TRUE;
  374. }
  375. else {
  376. return FALSE;
  377. }
  378. }
  379. /********************************************************************
  380. CleanupExit
  381. Routine Description:
  382. Does any cleanup and exits
  383. Arguments:
  384. ExitCode - exit code for exit()
  385. Return Value:
  386. does not return
  387. *******************************************************************/
  388. void
  389. CleanupExit ( int ExitCode )
  390. {
  391. if ( fNDS )
  392. NDSCleanup();
  393. exit( ExitCode );
  394. }
  395. /********************************************************************
  396. NTGetNWUserName
  397. Routine Description:
  398. Get NetWare user name
  399. Arguments:
  400. TreeBuffer IN - wide string for server or tree
  401. UserName OUT - user name
  402. Length IN - length of user name
  403. Return Value:
  404. error message
  405. *******************************************************************/
  406. int
  407. NTGetNWUserName( PWCHAR TreeBuffer, PWCHAR UserName, int Length )
  408. {
  409. NTSTATUS ntstatus;
  410. IO_STATUS_BLOCK IoStatusBlock;
  411. OBJECT_ATTRIBUTES ObjectAttributes;
  412. ACCESS_MASK DesiredAccess = SYNCHRONIZE | FILE_LIST_DIRECTORY;
  413. HANDLE hRdr;
  414. WCHAR DevicePreamble[] = L"\\Device\\Nwrdr\\";
  415. UINT PreambleLength = 14;
  416. WCHAR NameStr[64];
  417. UNICODE_STRING OpenName;
  418. UINT i;
  419. UNICODE_STRING NdsTree;
  420. //
  421. // Copy over the preamble.
  422. //
  423. OpenName.MaximumLength = sizeof( NameStr );
  424. for ( i = 0; i < PreambleLength ; i++ )
  425. NameStr[i] = DevicePreamble[i];
  426. RtlInitUnicodeString( &NdsTree, TreeBuffer );
  427. //
  428. // Copy the server or tree name.
  429. //
  430. for ( i = 0 ; i < ( NdsTree.Length / sizeof( WCHAR ) ) ; i++ ) {
  431. NameStr[i + PreambleLength] = NdsTree.Buffer[i];
  432. }
  433. OpenName.Length = (USHORT)(( i * sizeof( WCHAR ) ) +
  434. ( PreambleLength * sizeof( WCHAR ) ));
  435. OpenName.Buffer = NameStr;
  436. //
  437. // Set up the object attributes.
  438. //
  439. InitializeObjectAttributes( &ObjectAttributes,
  440. &OpenName,
  441. OBJ_CASE_INSENSITIVE,
  442. NULL,
  443. NULL );
  444. ntstatus = NtOpenFile( &hRdr,
  445. DesiredAccess,
  446. &ObjectAttributes,
  447. &IoStatusBlock,
  448. FILE_SHARE_VALID_FLAGS,
  449. FILE_SYNCHRONOUS_IO_NONALERT );
  450. if ( !NT_SUCCESS(ntstatus) )
  451. return ntstatus;
  452. ntstatus = NtFsControlFile( hRdr,
  453. NULL,
  454. NULL,
  455. NULL,
  456. &IoStatusBlock,
  457. FSCTL_NWR_GET_USERNAME,
  458. (PVOID) TreeBuffer,
  459. NdsTree.Length,
  460. (PVOID) UserName,
  461. Length );
  462. UserName[(USHORT)IoStatusBlock.Information/2] = 0;
  463. NtClose( hRdr );
  464. return ntstatus;
  465. }