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.

311 lines
9.1 KiB

  1. /*****************************************************************/
  2. /** Microsoft LAN Manager **/
  3. /** Copyright(c) Microsoft Corp., 1990 **/
  4. /*****************************************************************/
  5. /*
  6. MiscAPIs.cxx
  7. Miscallaneous APIs
  8. FILE HISTORY:
  9. jonn 14-Jan-1991 Split from winprof.cxx
  10. jonn 17-Jan-1991 Split off lm21util.cxx, lm30spfc.cxx
  11. jonn 02-Feb-1991 Removed unused routines
  12. rustanl 12-Apr-1991 Added UI_UNCPathCompare and
  13. UI_UNCPathValidate
  14. beng 17-May-1991 Correct lmui.hxx usage
  15. jonn 22-May-1991 Added MyNetUseAdd (was in winprof.cxx)
  16. rustanl 24-May-1991 Added AUTO_CURSOR to MyNetUseAdd
  17. terryk 31-Oct-1991 add mnet.h and change I_NetXXX to
  18. I_MNetXXX
  19. Yi-HsinS 31-Dec-1991 Unicode work
  20. terryk 10-Oct-1993 deleted MyNetUseAdd
  21. */
  22. #define INCL_WINDOWS
  23. #define INCL_WINDOWS_GDI
  24. #define INCL_DOSERRORS
  25. #define INCL_NETERRORS
  26. #define INCL_NETCONS
  27. #define INCL_NETACCESS
  28. #define INCL_NETSERVER
  29. #define INCL_NETWKSTA
  30. #define INCL_NETSERVICE
  31. #define INCL_NETLIB
  32. #define INCL_ICANON
  33. #define INCL_NETUSE // for NetUseAdd
  34. #define _WINNETWK_
  35. #include <lmui.hxx>
  36. #undef _WINNETWK_
  37. extern "C"
  38. {
  39. #include <mnet.h>
  40. #include <winnetwk.h>
  41. #include <npapi.h>
  42. #include <lmsname.h>
  43. }
  44. #include <uiassert.hxx>
  45. #include <uitrace.hxx>
  46. #include <string.hxx>
  47. #include <lmowks.hxx>
  48. #include <lmodom.hxx>
  49. #include <lmodev.hxx> // for DEVICE object
  50. #include <uibuffer.hxx>
  51. #include <strchlit.hxx> // for string and character literals
  52. #include <lmsvc.hxx>
  53. #include <miscapis.hxx>
  54. /* Local prototypes */
  55. /* functions */
  56. /*******************************************************************
  57. NAME: CheckLMService
  58. SYNOPSIS: Checks to make sure the LM Wksta service is willing to
  59. accept requests.
  60. RETURNS: NERR_Success if the service is happy happy
  61. WN_NO_NETWORK if the service is stopped or stopping
  62. WN_FUNCTION_BUSY if the service is starting
  63. Other error if an error occurred getting the status
  64. NOTES:
  65. HISTORY:
  66. Johnl 09-Sep-1992 Created
  67. ********************************************************************/
  68. APIERR CheckLMService( void )
  69. {
  70. APIERR err = NERR_Success ;
  71. //
  72. // we almost always hit the wksta soon after this call & the wksta
  73. // is usually started. so this check will avoid paging in the service
  74. // controller. it just ends up paging in the wksta a bit earlier.
  75. // only if the call fails do we hit the service controller for the
  76. // actual status.
  77. //
  78. WKSTA_10 wksta_10 ;
  79. if ( (wksta_10.QueryError() == NERR_Success) &&
  80. (wksta_10.GetInfo() == NERR_Success) )
  81. {
  82. return NERR_Success ;
  83. }
  84. LM_SERVICE service( NULL, (const TCHAR *)SERVICE_WORKSTATION );
  85. if ( err = service.QueryError() )
  86. {
  87. return err ;
  88. }
  89. switch ( service.QueryStatus( &err ) )
  90. {
  91. case LM_SVC_STOPPED:
  92. case LM_SVC_STOPPING:
  93. if ( !err )
  94. err = WN_NO_NETWORK ;
  95. TRACEEOL("::CheckLMService - Returning WN_NO_NETWORK") ;
  96. break ;
  97. case LM_SVC_STARTING:
  98. if ( !err )
  99. err = WN_FUNCTION_BUSY ;
  100. TRACEEOL("::CheckLMService - Returning WN_FUNCTION_BUSY") ;
  101. break ;
  102. case LM_SVC_STATUS_UNKNOWN:
  103. case LM_SVC_STARTED:
  104. case LM_SVC_PAUSED:
  105. case LM_SVC_PAUSING:
  106. case LM_SVC_CONTINUING:
  107. default:
  108. /* Return unadultered error code
  109. */
  110. break ;
  111. }
  112. return err ;
  113. }
  114. /*******************************************************************
  115. NAME: ParseRemoteName
  116. SYNOPSIS: Canonicalizes a remote resource name and determines
  117. its type
  118. ARGUMENTS:
  119. RemoteName - Remote resource name to be parsed
  120. CanonName - Buffer for canonicalized name, assumed to be
  121. MAX_PATH characters long
  122. CanonNameSize - Size, in bytes, of output buffer
  123. PathStart - Set to the offset, in characters, of the start
  124. of the "\share" portion (in the REMOTENAMETYPE_SHARE case)
  125. or the "\path" portion (in the REMOTENAMETYPE_PATH case)
  126. of the name within CanonName. Not set in other cases.
  127. RETURNS:
  128. If nlsRemote is like Then returns
  129. -------------------- ------------
  130. workgroup REMOTENAMETYPE_WORKGROUP
  131. \\server REMOTENAMETYPE_SERVER
  132. \\server\share REMOTENAMETYPE_SHARE
  133. \\server\share\path REMOTENAMETYPE_PATH
  134. (other) REMOTENAMETYPE_INVALID
  135. NOTES:
  136. HISTORY:
  137. AnirudhS 21-Apr-1995 Ported from Win95 sources - used netlib
  138. functions rather than ad hoc parsing, introduced comments
  139. ********************************************************************/
  140. REMOTENAMETYPE ParseRemoteName(
  141. IN LPWSTR RemoteName,
  142. OUT LPWSTR CanonName,
  143. IN DWORD CanonNameSize,
  144. OUT PULONG PathStart
  145. )
  146. {
  147. //
  148. // Determine the path type
  149. //
  150. DWORD PathType = 0;
  151. NET_API_STATUS Status = I_NetPathType(NULL, RemoteName, &PathType, 0);
  152. if (Status != NERR_Success)
  153. {
  154. return REMOTENAMETYPE_INVALID;
  155. }
  156. //
  157. // I_NetPathType doesn't give us quite as fine a classification of
  158. // path types as we need, so we still need to do a little more parsing
  159. //
  160. switch (PathType)
  161. {
  162. case ITYPE_PATH_RELND:
  163. //
  164. // A driveless relative path
  165. // A valid workgroup or domain name would be classified as
  166. // such, but it still needs to be validated as a workgroup name
  167. //
  168. Status = I_NetNameCanonicalize(
  169. NULL, // ServerName
  170. RemoteName, // Name
  171. CanonName, // Outbuf
  172. CanonNameSize, // OutbufLen
  173. NAMETYPE_WORKGROUP, // NameType
  174. 0 // Flags
  175. );
  176. if (Status == NERR_Success)
  177. {
  178. return REMOTENAMETYPE_WORKGROUP;
  179. }
  180. else
  181. {
  182. return REMOTENAMETYPE_INVALID;
  183. }
  184. case ITYPE_UNC_COMPNAME:
  185. //
  186. // A UNC computername, "\\server"
  187. //
  188. {
  189. //
  190. // HACK: I_NetPathCanonicalize likes "\\server\share" but not
  191. // "\\server", so append a dummy share name to canonicalize.
  192. // We assume that the CanonName buffer will still be big
  193. // enough (which it will, in the calls made from this file).
  194. //
  195. if (wcslen(RemoteName) + 3 > NNLEN)
  196. {
  197. return REMOTENAMETYPE_INVALID;
  198. }
  199. WCHAR wszDummy[NNLEN];
  200. wcscpy(wszDummy, RemoteName);
  201. wcscat(wszDummy, L"\\a");
  202. UIASSERT(CanonNameSize >= sizeof(wszDummy));
  203. PathType = ITYPE_UNC;
  204. Status = I_NetPathCanonicalize(
  205. NULL, // ServerName
  206. wszDummy, // PathName
  207. CanonName, // Outbuf
  208. CanonNameSize, // OutbufLen
  209. NULL, // Prefix
  210. &PathType, // PathType
  211. 0 // Flags
  212. );
  213. }
  214. if (Status != NERR_Success)
  215. {
  216. return REMOTENAMETYPE_INVALID;
  217. }
  218. CanonName[ wcslen(CanonName) - 2 ] = 0;
  219. return REMOTENAMETYPE_SERVER;
  220. case ITYPE_UNC:
  221. //
  222. // A UNC path, either "\\server\share" or "\\server\share\path" -
  223. // canonicalize and determine which one
  224. //
  225. Status = I_NetPathCanonicalize(
  226. NULL, // ServerName
  227. RemoteName, // PathName
  228. CanonName, // Outbuf
  229. CanonNameSize, // OutbufLen
  230. NULL, // Prefix
  231. &PathType, // PathType
  232. 0 // Flags
  233. );
  234. if (Status != NERR_Success)
  235. {
  236. return REMOTENAMETYPE_INVALID;
  237. }
  238. {
  239. WCHAR * pSlash = wcschr(CanonName+2, PATH_SEPARATOR);
  240. UIASSERT(pSlash);
  241. *PathStart = (ULONG)(pSlash - CanonName);
  242. // Look for a fourth slash
  243. pSlash = wcschr(pSlash+1, PATH_SEPARATOR);
  244. if (pSlash)
  245. {
  246. *PathStart = (ULONG)(pSlash - CanonName);
  247. return REMOTENAMETYPE_PATH;
  248. }
  249. else
  250. {
  251. return REMOTENAMETYPE_SHARE;
  252. }
  253. }
  254. default:
  255. return REMOTENAMETYPE_INVALID;
  256. }
  257. }