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.

382 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. sessdev.c
  5. Abstract:
  6. Per Session Dos Device access routines
  7. Author:
  8. Revision History:
  9. --*/
  10. #include "basedll.h"
  11. #define SESSION0_ROOT L"GLOBALROOT"
  12. #define SESSIONX_ROOT L"GLOBALROOT\\Sessions\\"
  13. BOOL
  14. WINAPI
  15. DosPathToSessionPathA(
  16. IN DWORD SessionId,
  17. IN LPCSTR pInPath,
  18. OUT LPSTR *ppOutPath
  19. )
  20. /*++
  21. Routine Description:
  22. Converts a DOS path relative to the current session to a DOS path
  23. that allows access to a specific session.
  24. Arguments:
  25. SessionId - SessionId to access.
  26. pInPath - WIN32 DOS path. Could be of the form "C:", "LPT1:",
  27. "C:\file\path", etc.
  28. ppOutPath - Output path that accesses the specified session.
  29. If pIniPath is "C:" and SessionId is 6, the output would be
  30. "GLOBALROOT\Sessions\6\DosDevices\C:".
  31. Return Value:
  32. TRUE - Path returned in *ppOutPath in newly allocated memory from
  33. LocalAlloc.
  34. FALSE - Call failed. Error code returned via GetLastError()
  35. --*/
  36. {
  37. BOOL rc;
  38. DWORD Len;
  39. PCHAR Buf;
  40. NTSTATUS Status;
  41. PWCHAR pOutPath;
  42. ANSI_STRING AnsiString;
  43. UNICODE_STRING UnicodeString;
  44. // if the input path is null or the pointer is a bad pointer, return
  45. // an error.
  46. if( (pInPath == 0) ||
  47. (IsBadReadPtr( pInPath, sizeof( CHAR ))) ||
  48. (IsBadWritePtr( ppOutPath, sizeof(LPSTR) )) ) {
  49. SetLastError(ERROR_INVALID_PARAMETER);
  50. return(FALSE);
  51. }
  52. try {
  53. RtlInitAnsiString( &AnsiString, pInPath );
  54. Status = RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, TRUE );
  55. } except (EXCEPTION_EXECUTE_HANDLER) {
  56. Status = GetExceptionCode();
  57. }
  58. if (!NT_SUCCESS( Status )) {
  59. BaseSetLastNTError( Status );
  60. return FALSE;
  61. }
  62. rc = DosPathToSessionPathW(
  63. SessionId,
  64. UnicodeString.Buffer,
  65. &pOutPath
  66. );
  67. RtlFreeUnicodeString( &UnicodeString );
  68. if( !rc ) {
  69. return( rc );
  70. }
  71. RtlInitUnicodeString( &UnicodeString, pOutPath );
  72. Status = RtlUnicodeStringToAnsiString( &AnsiString, &UnicodeString, TRUE );
  73. if (!NT_SUCCESS( Status )) {
  74. BaseSetLastNTError( Status );
  75. LocalFree( pOutPath );
  76. return FALSE;
  77. }
  78. Len = strlen( AnsiString.Buffer ) + 1;
  79. Buf = LocalAlloc(LMEM_FIXED, Len);
  80. if( Buf == NULL ) {
  81. LocalFree( pOutPath );
  82. RtlFreeAnsiString( &AnsiString );
  83. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  84. return(FALSE);
  85. }
  86. strcpy( Buf, AnsiString.Buffer );
  87. *ppOutPath = Buf;
  88. LocalFree( pOutPath );
  89. RtlFreeAnsiString( &AnsiString );
  90. return(TRUE);
  91. }
  92. BOOL
  93. WINAPI
  94. DosPathToSessionPathW(
  95. IN DWORD SessionId,
  96. IN LPCWSTR pInPath,
  97. OUT LPWSTR *ppOutPath
  98. )
  99. /*++
  100. Routine Description:
  101. Converts a DOS path relative to the current session to a DOS path
  102. that allows access to a specific session.
  103. Arguments:
  104. SessionId - SessionId to access.
  105. pInPath - WIN32 DOS path. Could be of the form "C:", "LPT1:",
  106. "C:\file\path", etc.
  107. ppOutPath - Output path that accesses the specified session.
  108. If pIniPath is "C:" and SessionId is 6, the output would be
  109. "GLOBALROOT\Sessions\6\DosDevices\C:".
  110. Return Value:
  111. TRUE - Path returned in *ppOutPath in newly allocated memory from
  112. LocalAlloc.
  113. FALSE - Call failed. Error code returned via GetLastError()
  114. --*/
  115. {
  116. PWCHAR Buf;
  117. ULONG Len;
  118. //
  119. // SessionId 0 has no per session object directories.
  120. //
  121. if (BaseStaticServerData->LUIDDeviceMapsEnabled == TRUE) {
  122. Len = 0;
  123. } else {
  124. if( SessionId == 0 ) {
  125. Len = wcslen(SESSION0_ROOT);
  126. }
  127. else {
  128. Len = wcslen(SESSIONX_ROOT);
  129. Len += 10; // Max DWORD width
  130. }
  131. }
  132. Len += 13; // \DosDevices\ ... <NULL>
  133. // if the input path is null or the pointer is a bad pointer, return
  134. // an error.
  135. if( (pInPath == 0) ||
  136. (IsBadReadPtr( pInPath, sizeof( WCHAR ))) ||
  137. (IsBadWritePtr( ppOutPath, sizeof(LPWSTR) )) ) {
  138. SetLastError(ERROR_INVALID_PARAMETER);
  139. return(FALSE);
  140. }
  141. Len += wcslen(pInPath);
  142. Buf = LocalAlloc(LMEM_FIXED, Len * sizeof(WCHAR));
  143. if( Buf == NULL ) {
  144. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  145. return(FALSE);
  146. }
  147. try {
  148. if (BaseStaticServerData->LUIDDeviceMapsEnabled == TRUE) {
  149. // C: -> C:
  150. swprintf(
  151. Buf,
  152. L"%ws",
  153. pInPath
  154. );
  155. } else {
  156. if( SessionId == 0 ) {
  157. // C: -> GLOBALROOT\DosDevices\C:
  158. swprintf(
  159. Buf,
  160. L"%ws\\DosDevices\\%ws",
  161. SESSION0_ROOT,
  162. pInPath
  163. );
  164. }
  165. else {
  166. // C: -> GLOBALROOT\Sessions\6\DosDevices\C:
  167. swprintf(
  168. Buf,
  169. L"%ws%u\\DosDevices\\%ws",
  170. SESSIONX_ROOT,
  171. SessionId,
  172. pInPath
  173. );
  174. }
  175. }
  176. *ppOutPath = Buf;
  177. } except (EXCEPTION_EXECUTE_HANDLER) {
  178. BaseSetLastNTError(GetExceptionCode());
  179. return(FALSE);
  180. }
  181. return(TRUE);
  182. }
  183. BOOL
  184. WINAPI
  185. ProcessIdToSessionId(
  186. IN DWORD dwProcessId,
  187. OUT DWORD *pSessionId
  188. )
  189. /*++
  190. Routine Description:
  191. Given a ProcessId, return the SessionId.
  192. This is useful for services that impersonate a caller, and
  193. redefine a drive letter for the caller. An example is the
  194. workstation service. Transport specific routines allow the
  195. ProcessId of the caller to be retrieved.
  196. Arguments:
  197. Process - Process identifies process to
  198. return the SessionId for.
  199. pSessionId - returned SessionId.
  200. Return Value:
  201. TRUE - SessionId returned in *pSessionId
  202. FALSE - Call failed. Error code returned via GetLastError()
  203. --*/
  204. {
  205. HANDLE Handle;
  206. NTSTATUS Status;
  207. CLIENT_ID ClientId;
  208. OBJECT_ATTRIBUTES Obja;
  209. PROCESS_SESSION_INFORMATION Info;
  210. if( IsBadWritePtr( pSessionId, sizeof(DWORD) ) ) {
  211. SetLastError(ERROR_INVALID_PARAMETER);
  212. return FALSE;
  213. }
  214. InitializeObjectAttributes(
  215. &Obja,
  216. NULL,
  217. 0,
  218. NULL,
  219. NULL
  220. );
  221. ClientId.UniqueProcess = (HANDLE) LongToHandle(dwProcessId);
  222. ClientId.UniqueThread = (HANDLE)NULL;
  223. Status = NtOpenProcess(
  224. &Handle,
  225. (ACCESS_MASK)PROCESS_QUERY_INFORMATION,
  226. &Obja,
  227. &ClientId
  228. );
  229. if( !NT_SUCCESS(Status) ) {
  230. SetLastError(RtlNtStatusToDosError(Status));
  231. return(FALSE);
  232. }
  233. Status = NtQueryInformationProcess(
  234. Handle,
  235. ProcessSessionInformation,
  236. &Info,
  237. sizeof(Info),
  238. NULL
  239. );
  240. if( !NT_SUCCESS(Status) ) {
  241. NtClose( Handle );
  242. SetLastError(RtlNtStatusToDosError(Status));
  243. return(FALSE);
  244. }
  245. *pSessionId = Info.SessionId;
  246. NtClose( Handle );
  247. return(TRUE);
  248. }
  249. DWORD
  250. WINAPI
  251. WTSGetActiveConsoleSessionId ()
  252. /*++
  253. Routine Description:
  254. returns the Session ID for the session, attached to Console.
  255. Arguments:
  256. none
  257. Return Value:
  258. SessionID for the console (session attached to console not necessarily session 0 ) session.
  259. return 0xFFFFFFFF if there is no session attached to console.
  260. This could happen if session disconnect / connect is taking place
  261. This is a session id for the session currently connected to console, it changes when
  262. new session is connected at console. to keep track of the current console sesion, use
  263. WTSRegisterSessionNotification
  264. --*/
  265. {
  266. return (USER_SHARED_DATA->ActiveConsoleId);
  267. }