VirtualBox

source: vbox/trunk/src/VBox/Main/include/GuestSessionImpl.h@ 95385

Last change on this file since 95385 was 95385, checked in by vboxsync, 2 years ago

Guest Control/Main: Added IFsInfo, IGuestFsInfo, IGuestSession::fsQueryFreeSpace() + IGuestSession::fsQueryInfo() stubs for retrieving file system information. bugref:9500

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.1 KB
Line 
1/* $Id: GuestSessionImpl.h 95385 2022-06-27 09:04:31Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest session handling.
4 */
5
6/*
7 * Copyright (C) 2012-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef MAIN_INCLUDED_GuestSessionImpl_h
19#define MAIN_INCLUDED_GuestSessionImpl_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include "GuestSessionWrap.h"
25#include "EventImpl.h"
26
27#include "GuestCtrlImplPrivate.h"
28#include "GuestProcessImpl.h"
29#include "GuestDirectoryImpl.h"
30#include "GuestFileImpl.h"
31#include "GuestFsObjInfoImpl.h"
32#include "GuestSessionImplTasks.h"
33
34#include <iprt/asm.h> /** @todo r=bird: Needed for ASMBitSet() in GuestSession::Data constructor. Removed when
35 * that is moved into the class implementation file as it should be. */
36#include <deque>
37
38class GuestSessionTaskInternalStart; /* Needed for i_startSessionThreadTask(). */
39
40/**
41 * Guest session implementation.
42 */
43class ATL_NO_VTABLE GuestSession
44 : public GuestSessionWrap
45 , public GuestBase
46{
47public:
48 /** @name COM and internal init/term/mapping cruft.
49 * @{ */
50 DECLARE_COMMON_CLASS_METHODS(GuestSession)
51
52 int init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds);
53 void uninit(void);
54 HRESULT FinalConstruct(void);
55 void FinalRelease(void);
56 /** @} */
57
58private:
59
60 /** Wrapped @name IGuestSession properties.
61 * @{ */
62 HRESULT getUser(com::Utf8Str &aUser);
63 HRESULT getDomain(com::Utf8Str &aDomain);
64 HRESULT getName(com::Utf8Str &aName);
65 HRESULT getId(ULONG *aId);
66 HRESULT getTimeout(ULONG *aTimeout);
67 HRESULT setTimeout(ULONG aTimeout);
68 HRESULT getProtocolVersion(ULONG *aProtocolVersion);
69 HRESULT getStatus(GuestSessionStatus_T *aStatus);
70 HRESULT getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges);
71 HRESULT setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges);
72 HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase);
73 HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses);
74 HRESULT getPathStyle(PathStyle_T *aPathStyle);
75 HRESULT getCurrentDirectory(com::Utf8Str &aCurrentDirectory);
76 HRESULT setCurrentDirectory(const com::Utf8Str &aCurrentDirectory);
77 HRESULT getUserDocuments(com::Utf8Str &aUserDocuments);
78 HRESULT getUserHome(com::Utf8Str &aUserHome);
79 HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories);
80 HRESULT getFiles(std::vector<ComPtr<IGuestFile> > &aFiles);
81 HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
82 /** @} */
83
84 /** Wrapped @name IGuestSession methods.
85 * @{ */
86 HRESULT close();
87
88 HRESULT copyFromGuest(const std::vector<com::Utf8Str> &aSources,
89 const std::vector<com::Utf8Str> &aFilters,
90 const std::vector<com::Utf8Str> &aFlags,
91 const com::Utf8Str &aDestination,
92 ComPtr<IProgress> &aProgress);
93 HRESULT copyToGuest(const std::vector<com::Utf8Str> &aSources,
94 const std::vector<com::Utf8Str> &aFilters,
95 const std::vector<com::Utf8Str> &aFlags,
96 const com::Utf8Str &aDestination,
97 ComPtr<IProgress> &aProgress);
98
99 HRESULT directoryCopy(const com::Utf8Str &aSource,
100 const com::Utf8Str &aDestination,
101 const std::vector<DirectoryCopyFlag_T> &aFlags,
102 ComPtr<IProgress> &aProgress);
103 HRESULT directoryCopyFromGuest(const com::Utf8Str &aSource,
104 const com::Utf8Str &aDestination,
105 const std::vector<DirectoryCopyFlag_T> &aFlags,
106 ComPtr<IProgress> &aProgress);
107 HRESULT directoryCopyToGuest(const com::Utf8Str &aSource,
108 const com::Utf8Str &aDestination,
109 const std::vector<DirectoryCopyFlag_T> &aFlags,
110 ComPtr<IProgress> &aProgress);
111 HRESULT directoryCreate(const com::Utf8Str &aPath,
112 ULONG aMode,
113 const std::vector<DirectoryCreateFlag_T> &aFlags);
114 HRESULT directoryCreateTemp(const com::Utf8Str &aTemplateName,
115 ULONG aMode,
116 const com::Utf8Str &aPath,
117 BOOL aSecure,
118 com::Utf8Str &aDirectory);
119 HRESULT directoryExists(const com::Utf8Str &aPath,
120 BOOL aFollowSymlinks,
121 BOOL *aExists);
122 HRESULT directoryOpen(const com::Utf8Str &aPath,
123 const com::Utf8Str &aFilter,
124 const std::vector<DirectoryOpenFlag_T> &aFlags,
125 ComPtr<IGuestDirectory> &aDirectory);
126 HRESULT directoryRemove(const com::Utf8Str &aPath);
127 HRESULT directoryRemoveRecursive(const com::Utf8Str &aPath,
128 const std::vector<DirectoryRemoveRecFlag_T> &aFlags,
129 ComPtr<IProgress> &aProgress);
130 HRESULT environmentScheduleSet(const com::Utf8Str &aName,
131 const com::Utf8Str &aValue);
132 HRESULT environmentScheduleUnset(const com::Utf8Str &aName);
133 HRESULT environmentGetBaseVariable(const com::Utf8Str &aName,
134 com::Utf8Str &aValue);
135 HRESULT environmentDoesBaseVariableExist(const com::Utf8Str &aName,
136 BOOL *aExists);
137
138 HRESULT fileCopy(const com::Utf8Str &aSource,
139 const com::Utf8Str &aDestination,
140 const std::vector<FileCopyFlag_T> &aFlags,
141 ComPtr<IProgress> &aProgress);
142 HRESULT fileCopyToGuest(const com::Utf8Str &aSource,
143 const com::Utf8Str &aDestination,
144 const std::vector<FileCopyFlag_T> &aFlags,
145 ComPtr<IProgress> &aProgress);
146 HRESULT fileCopyFromGuest(const com::Utf8Str &aSource,
147 const com::Utf8Str &aDestination,
148 const std::vector<FileCopyFlag_T> &aFlags,
149 ComPtr<IProgress> &aProgress);
150 HRESULT fileCreateTemp(const com::Utf8Str &aTemplateName,
151 ULONG aMode,
152 const com::Utf8Str &aPath,
153 BOOL aSecure,
154 ComPtr<IGuestFile> &aFile);
155 HRESULT fileExists(const com::Utf8Str &aPath,
156 BOOL aFollowSymlinks,
157 BOOL *aExists);
158 HRESULT fileOpen(const com::Utf8Str &aPath,
159 FileAccessMode_T aAccessMode,
160 FileOpenAction_T aOpenAction,
161 ULONG aCreationMode,
162 ComPtr<IGuestFile> &aFile);
163 HRESULT fileOpenEx(const com::Utf8Str &aPath,
164 FileAccessMode_T aAccessMode,
165 FileOpenAction_T aOpenAction,
166 FileSharingMode_T aSharingMode,
167 ULONG aCreationMode,
168 const std::vector<FileOpenExFlag_T> &aFlags,
169 ComPtr<IGuestFile> &aFile);
170 HRESULT fileQuerySize(const com::Utf8Str &aPath,
171 BOOL aFollowSymlinks,
172 LONG64 *aSize);
173 HRESULT fsQueryFreeSpace(const com::Utf8Str &aPath, LONG64 *aFreeSpace);
174 HRESULT fsQueryInfo(const com::Utf8Str &aPath, ComPtr<IGuestFsInfo> &aInfo);
175 HRESULT fsObjExists(const com::Utf8Str &aPath,
176 BOOL aFollowSymlinks,
177 BOOL *pfExists);
178 HRESULT fsObjQueryInfo(const com::Utf8Str &aPath,
179 BOOL aFollowSymlinks,
180 ComPtr<IGuestFsObjInfo> &aInfo);
181 HRESULT fsObjRemove(const com::Utf8Str &aPath);
182 HRESULT fsObjRemoveArray(const std::vector<com::Utf8Str> &aPaths,
183 ComPtr<IProgress> &aProgress);
184 HRESULT fsObjRename(const com::Utf8Str &aOldPath,
185 const com::Utf8Str &aNewPath,
186 const std::vector<FsObjRenameFlag_T> &aFlags);
187 HRESULT fsObjMove(const com::Utf8Str &aSource,
188 const com::Utf8Str &aDestination,
189 const std::vector<FsObjMoveFlag_T> &aFlags,
190 ComPtr<IProgress> &aProgress);
191 HRESULT fsObjMoveArray(const std::vector<com::Utf8Str> &aSource,
192 const com::Utf8Str &aDestination,
193 const std::vector<FsObjMoveFlag_T> &aFlags,
194 ComPtr<IProgress> &aProgress);
195 HRESULT fsObjCopyArray(const std::vector<com::Utf8Str> &aSource,
196 const com::Utf8Str &aDestination,
197 const std::vector<FileCopyFlag_T> &aFlags,
198 ComPtr<IProgress> &aProgress);
199 HRESULT fsObjSetACL(const com::Utf8Str &aPath,
200 BOOL aFollowSymlinks,
201 const com::Utf8Str &aAcl,
202 ULONG aMode);
203 HRESULT processCreate(const com::Utf8Str &aCommand,
204 const std::vector<com::Utf8Str> &aArguments,
205 const std::vector<com::Utf8Str> &aEnvironment,
206 const std::vector<ProcessCreateFlag_T> &aFlags,
207 ULONG aTimeoutMS,
208 ComPtr<IGuestProcess> &aGuestProcess);
209 HRESULT processCreateEx(const com::Utf8Str &aCommand,
210 const std::vector<com::Utf8Str> &aArguments,
211 const std::vector<com::Utf8Str> &aEnvironment,
212 const std::vector<ProcessCreateFlag_T> &aFlags,
213 ULONG aTimeoutMS,
214 ProcessPriority_T aPriority,
215 const std::vector<LONG> &aAffinity,
216 ComPtr<IGuestProcess> &aGuestProcess);
217 HRESULT processGet(ULONG aPid,
218 ComPtr<IGuestProcess> &aGuestProcess);
219 HRESULT symlinkCreate(const com::Utf8Str &aSource,
220 const com::Utf8Str &aTarget,
221 SymlinkType_T aType);
222 HRESULT symlinkExists(const com::Utf8Str &aSymlink,
223 BOOL *aExists);
224 HRESULT symlinkRead(const com::Utf8Str &aSymlink,
225 const std::vector<SymlinkReadFlag_T> &aFlags,
226 com::Utf8Str &aTarget);
227 HRESULT waitFor(ULONG aWaitFor,
228 ULONG aTimeoutMS,
229 GuestSessionWaitResult_T *aReason);
230 HRESULT waitForArray(const std::vector<GuestSessionWaitForFlag_T> &aWaitFor,
231 ULONG aTimeoutMS,
232 GuestSessionWaitResult_T *aReason);
233 /** @} */
234
235 /** Map of guest directories. The key specifies the internal directory ID. */
236 typedef std::map <uint32_t, ComObjPtr<GuestDirectory> > SessionDirectories;
237 /** Map of guest files. The key specifies the internal file ID. */
238 typedef std::map <uint32_t, ComObjPtr<GuestFile> > SessionFiles;
239 /** Map of guest processes. The key specifies the internal process number.
240 * To retrieve the process' guest PID use the Id() method of the IProcess interface. */
241 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
242
243 /** Guest session object type enumeration. */
244 enum SESSIONOBJECTTYPE
245 {
246 /** Invalid session object type. */
247 SESSIONOBJECTTYPE_INVALID = 0,
248 /** Session object. */
249 SESSIONOBJECTTYPE_SESSION = 1,
250 /** Directory object. */
251 SESSIONOBJECTTYPE_DIRECTORY = 2,
252 /** File object. */
253 SESSIONOBJECTTYPE_FILE = 3,
254 /** Process object. */
255 SESSIONOBJECTTYPE_PROCESS = 4
256 };
257
258 struct SessionObject
259 {
260 /** Creation timestamp (in ms).
261 * @note not used by anyone at the moment. */
262 uint64_t msBirth;
263 /** The object type. */
264 SESSIONOBJECTTYPE enmType;
265 /** Weak pointer to the object itself.
266 * Is NULL for SESSIONOBJECTTYPE_SESSION because GuestSession doesn't
267 * inherit from GuestObject. */
268 GuestObject *pObject;
269 };
270
271 /** Map containing all objects bound to a guest session.
272 * The key specifies the (global) context ID. */
273 typedef std::map<uint32_t, SessionObject> SessionObjects;
274
275public:
276 /** @name Public internal methods.
277 * @todo r=bird: Most of these are public for no real reason...
278 * @{ */
279 HRESULT i_copyFromGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
280 ComPtr<IProgress> &pProgress);
281 HRESULT i_copyToGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
282 ComPtr<IProgress> &pProgress);
283 int i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
284 HRESULT i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags);
285 bool i_directoryExists(const Utf8Str &strPath);
286 inline bool i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
287 int i_directoryUnregister(GuestDirectory *pDirectory);
288 int i_directoryRemove(const Utf8Str &strPath, uint32_t fFlags, int *pGuestRc);
289 int i_directoryCreate(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pGuestRc);
290 int i_directoryOpen(const GuestDirectoryOpenInfo &openInfo,
291 ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc);
292 int i_directoryQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
293 int i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
294 int i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
295 HRESULT i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags);
296 inline bool i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
297 int i_fileUnregister(GuestFile *pFile);
298 int i_fileRemove(const Utf8Str &strPath, int *pGuestRc);
299 int i_fileOpenEx(const com::Utf8Str &aPath, FileAccessMode_T aAccessMode, FileOpenAction_T aOpenAction,
300 FileSharingMode_T aSharingMode, ULONG aCreationMode,
301 const std::vector<FileOpenExFlag_T> &aFlags,
302 ComObjPtr<GuestFile> &pFile, int *prcGuest);
303 int i_fileOpen(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc);
304 int i_fileQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
305 int i_fileQuerySize(const Utf8Str &strPath, bool fFollowSymlinks, int64_t *pllSize, int *pGuestRc);
306 int i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
307 Utf8Str &strName, uint32_t fMode, bool fSecure, int *pGuestRc);
308 int i_fsQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
309 const GuestCredentials &i_getCredentials(void);
310 EventSource *i_getEventSource(void) { return mEventSource; }
311 Utf8Str i_getName(void);
312 ULONG i_getId(void) { return mData.mSession.mID; }
313 bool i_isStarted(void) const;
314 HRESULT i_isStartedExternal(void);
315 bool i_isTerminated(void) const;
316 int i_onRemove(void);
317 int i_onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
318 PathStyle_T i_getPathStyle(void);
319 int i_startSession(int *pGuestRc);
320 int i_startSessionAsync(void);
321 Guest *i_getParent(void) { return mParent; }
322 uint32_t i_getProtocolVersion(void) { return mData.mProtocolVersion; }
323 int i_objectRegister(GuestObject *pObject, SESSIONOBJECTTYPE enmType, uint32_t *pidObject);
324 int i_objectUnregister(uint32_t uObjectID);
325 int i_objectsUnregister(void);
326 int i_objectsNotifyAboutStatusChange(GuestSessionStatus_T enmSessionStatus);
327 int i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *pGuestRc);
328 int i_pathUserDocuments(Utf8Str &strPath, int *prcGuest);
329 int i_pathUserHome(Utf8Str &strPath, int *prcGuest);
330 int i_processUnregister(GuestProcess *pProcess);
331 int i_processCreateEx(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
332 inline bool i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
333 inline int i_processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
334 int i_sendMessage(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms,
335 uint64_t fDst = VBOX_GUESTCTRL_DST_SESSION);
336 int i_setSessionStatus(GuestSessionStatus_T sessionStatus, int sessionRc);
337 int i_signalWaiters(GuestSessionWaitResult_T enmWaitResult, int rc /*= VINF_SUCCESS */);
338 int i_shutdown(uint32_t fFlags, int *prcGuest);
339 int i_determineProtocolVersion(void);
340 int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pGuestRc);
341 int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS,
342 GuestSessionStatus_T *pSessionStatus, int *pGuestRc);
343 /** @} */
344
345public:
346
347 /** @name Static helper methods.
348 * @{ */
349 static Utf8Str i_guestErrorToString(int guestRc);
350 static bool i_isTerminated(GuestSessionStatus_T enmStatus);
351 static int i_startSessionThreadTask(GuestSessionTaskInternalStart *pTask);
352 /** @} */
353
354private:
355
356 /** Pointer to the parent (Guest). */
357 Guest *mParent;
358 /**
359 * The session's event source. This source is used for
360 * serving the internal listener as well as all other
361 * external listeners that may register to it.
362 *
363 * Note: This can safely be used without holding any locks.
364 * An AutoCaller suffices to prevent it being destroy while in use and
365 * internally there is a lock providing the necessary serialization.
366 */
367 const ComObjPtr<EventSource> mEventSource;
368
369 /** @todo r=bird: One of the core points of the DATA sub-structures in Main is
370 * hinding implementation details and stuff that requires including iprt/asm.h.
371 * The way it's used here totally defeats that purpose. You need to make it
372 * a pointer to a anynmous Data struct and define that structure in
373 * GuestSessionImpl.cpp and allocate it in the Init() function.
374 */
375 struct Data
376 {
377 /** The session credentials. */
378 GuestCredentials mCredentials;
379 /** The session's startup info. */
380 GuestSessionStartupInfo mSession;
381 /** The session's object ID.
382 * Needed for registering wait events which are bound directly to this session. */
383 uint32_t mObjectID;
384 /** The session's current status. */
385 GuestSessionStatus_T mStatus;
386 /** The set of environment changes for the session for use when
387 * creating new guest processes. */
388 GuestEnvironmentChanges mEnvironmentChanges;
389 /** Pointer to the immutable base environment for the session.
390 * @note This is not allocated until the guest reports it to the host. It is
391 * also shared with child processes.
392 * @todo This is actually not yet implemented, see
393 * GuestSession::i_onSessionStatusChange. */
394 GuestEnvironment const *mpBaseEnvironment;
395 /** Directory objects bound to this session. */
396 SessionDirectories mDirectories;
397 /** File objects bound to this session. */
398 SessionFiles mFiles;
399 /** Process objects bound to this session. */
400 SessionProcesses mProcesses;
401 /** Map of registered session objects (files, directories, ...). */
402 SessionObjects mObjects;
403 /** Guest control protocol version to be used.
404 * Guest Additions < VBox 4.3 have version 1,
405 * any newer version will have version 2. */
406 uint32_t mProtocolVersion;
407 /** Session timeout (in ms). */
408 uint32_t mTimeout;
409 /** The last returned session status
410 * returned from the guest side. */
411 int mRC;
412 /** Object ID allocation bitmap; clear bits are free, set bits are busy. */
413 uint64_t bmObjectIds[VBOX_GUESTCTRL_MAX_OBJECTS / sizeof(uint64_t) / 8];
414
415 Data(void)
416 : mpBaseEnvironment(NULL)
417 {
418 RT_ZERO(bmObjectIds);
419 ASMBitSet(&bmObjectIds, VBOX_GUESTCTRL_MAX_OBJECTS - 1); /* Reserved for the session itself? */
420 ASMBitSet(&bmObjectIds, 0); /* Let's reserve this too. */
421 }
422 Data(const Data &rThat)
423 : mCredentials(rThat.mCredentials)
424 , mSession(rThat.mSession)
425 , mStatus(rThat.mStatus)
426 , mEnvironmentChanges(rThat.mEnvironmentChanges)
427 , mpBaseEnvironment(NULL)
428 , mDirectories(rThat.mDirectories)
429 , mFiles(rThat.mFiles)
430 , mProcesses(rThat.mProcesses)
431 , mObjects(rThat.mObjects)
432 , mProtocolVersion(rThat.mProtocolVersion)
433 , mTimeout(rThat.mTimeout)
434 , mRC(rThat.mRC)
435 {
436 memcpy(&bmObjectIds, &rThat.bmObjectIds, sizeof(bmObjectIds));
437 }
438 ~Data(void)
439 {
440 if (mpBaseEnvironment)
441 {
442 mpBaseEnvironment->releaseConst();
443 mpBaseEnvironment = NULL;
444 }
445 }
446 } mData;
447};
448
449#endif /* !MAIN_INCLUDED_GuestSessionImpl_h */
450
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette