Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1066 lines
26 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
fileinit.c
Abstract:
This module implements the OS/2 V2.0 file system initialization
Author:
Therese Stowell (thereses) 14-Dec-1989
Revision History:
--*/
#define INCL_OS2V20_ERRORS
#define INCL_OS2V20_FILESYS
#define INCL_OS2V20_TASKING
#include "os2dll.h"
#include "conrqust.h"
#include "os2win.h"
#include <direct.h>
#include <stdlib.h>
/* When GetEnvironmentVariableW will return the correct mapping
uncomment the following line (and remove the code) */
//#define OS2SS_WIN32_GET_ENV_IN_UNICODE 1
DWORD
GetCurrentDirectoryW(
DWORD nBufferLength,
LPWSTR lpBuffer
);
BOOL
SetCurrentDirectoryW(
LPWSTR lpPathName
);
DWORD
GetEnvironmentVariableW(
LPWSTR lpName,
LPWSTR lpBuffer,
DWORD nSize
);
VOID
AllocateCurrentDirectory(
PSTRING CurrentDirectoryString,
HANDLE CurrentDirectoryHandle
);
NTSTATUS
Od2InitializeSessionDrives(
OUT PULONG CurrentDisk
);
ULONG
Od2Oem_getcwd(
LPSTR lpBuffer,
DWORD nBufferLength
)
/*++
Routine Description:
This routine return the current directory ("Drv:\...").
Arguments:
lpBuffer - buffer pointer for the output.
nBufferLength - buffer length.
Return Value:
0 - OK.
non-zero - the require buffer size.
Note:
Like _getcwd(lpBuffer, nBufferLength).
--*/
{
ULONG Length, Rc = NO_ERROR;
WCHAR wBuffer[260];
UNICODE_STRING Buffer_U;
ANSI_STRING Buffer_A;
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_getcwd: (drive %ld), Length %d\n",
Od2CurrentDisk, nBufferLength);
}
#endif
if (nBufferLength > 260)
{
nBufferLength = 260;
}
if (nBufferLength < 4)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
if (!(Length = GetCurrentDirectoryW(nBufferLength, wBuffer)) ||
(Length >= nBufferLength))
{
if (Length)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
ASSERT(FALSE);
Rc = GetLastError();
}
} else
{
if (wBuffer[0] >= L'a' && wBuffer[0] <= L'z') {
//
// upcase the drive letter
//
wBuffer[0] = wBuffer[0] - (L'a' - L'A');
}
RtlInitUnicodeString( &Buffer_U, wBuffer );
// RtlUpcaseUnicodeString( &Buffer_U, &Buffer_U, FALSE );
Buffer_A.Buffer = lpBuffer;
Buffer_A.Length = 0;
Buffer_A.MaximumLength = (USHORT)nBufferLength;
Or2UnicodeStringToMBString (&Buffer_A, &Buffer_U, FALSE);
}
}
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_getcwd: return %ld\n", Rc );
}
#endif
return(Rc);
}
ULONG
Od2Oem_getdcwd(
ULONG DiskNumber,
LPSTR lpBuffer,
DWORD nBufferLength
)
/*++
Routine Description:
This routine return the current directory ("Drv:\...") for specified drive.
Arguments:
DiskNumber- Disk drive (1=A, 2=B, ...)
lpBuffer - buffer pointer for the output.
nBufferLength - buffer length.
Return Value:
0 - OK.
non-zero - the require buffer size.
Note:
Like _getdcwd(DiskNumber, lpBuffer, nBufferLength).
--*/
{
ULONG Length, LogicalDrivesMap, Rc = NO_ERROR;
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
WCHAR wBuffer[300];
UNICODE_STRING Buffer_U;
ANSI_STRING Buffer_A;
WCHAR lpDriveName[] = L"=@:";
#else
CHAR lpDriveName[] = "=@:";
#endif
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_getdcwd: for drive %ld, (drive %ld), Length %d\n",
DiskNumber, Od2CurrentDisk, nBufferLength);
}
#endif
if (nBufferLength < 4)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else if (!(LogicalDrivesMap = GetLogicalDrives()) ||
!(LogicalDrivesMap & (1 << DiskNumber - 1 )))
{
Rc = ERROR_INVALID_DRIVE;
} else
{
lpBuffer[0] = '@' + (CHAR)DiskNumber;
lpBuffer[1] = ':';
lpBuffer[2] = '\\';
lpBuffer[3] = '\0';
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
if (nBufferLength > 300)
{
nBufferLength = 300;
}
lpDriveName[1] += (WCHAR)DiskNumber;
if (!(Length = GetEnvironmentVariableW(lpDriveName, wBuffer, nBufferLength)) ||
(Length >= nBufferLength))
{
if (Length)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
}
} else
{
RtlInitUnicodeString( &Buffer_U, wBuffer );
Buffer_A.Buffer = lpBuffer;
Buffer_A.Length = 0;
Buffer_A.MaximumLength = (USHORT)nBufferLength;
Or2UnicodeStringToMBString (&Buffer_A, &Buffer_U, FALSE);
}
#else
lpDriveName[1] += (CHAR)DiskNumber;
if ((Length = GetEnvironmentVariableA(lpDriveName, lpBuffer, nBufferLength)) >= nBufferLength)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
}
#endif
}
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_getdcwd: return %ld\n", Rc );
}
#endif
return(Rc);
}
ULONG
Od2Oem_chdrive(
ULONG DiskNumber
)
/*++
Routine Description:
This routine changes the current working drive
Arguments:
DiskNumber- Disk drive (1=A, 2=B, ...)
Return Value:
0 - OK.
non-zero - error.
Note:
Like : _chdrive(lpBuffer[0] - '@')
--*/
{
ULONG Length, LogicalDrivesMap, Rc = NO_ERROR;
UNICODE_STRING Buffer_U;
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
WCHAR wBuffer[300];
WCHAR lpDriveName[] = L"=@:";
#else
CHAR lpDriveName[] = "=@:";
CHAR lpBuffer[300];
BOOL bRc = FALSE;
#endif
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_chdrive: for drive %ld, (drive %ld)\n",
DiskNumber, Od2CurrentDisk);
}
#endif
if (!(LogicalDrivesMap = GetLogicalDrives()) ||
!(LogicalDrivesMap & (1 << DiskNumber - 1)))
{
Rc = ERROR_INVALID_DRIVE;
} else
{
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
wBuffer[0] = L'@' + (WCHAR)DiskNumber;
wBuffer[1] = L':';
wBuffer[2] = L'\\';
wBuffer[3] = L'\0';
lpDriveName[1] += (WCHAR)DiskNumber;
if ((Length = GetEnvironmentVariableW(lpDriveName, wBuffer, 300)) >= 300)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
bRc = !SetCurrentDirectoryW(wBuffer);
#else
lpBuffer[0] = '@' + (CHAR)DiskNumber;
lpBuffer[1] = ':';
lpBuffer[2] = '\\';
lpBuffer[3] = '\0';
lpDriveName[1] += (CHAR)DiskNumber;
if ((Length = GetEnvironmentVariableA(lpDriveName, lpBuffer, 300)) >= 300)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
if (!Od2CreateUnicodeStringFromMBz(&Buffer_U, lpBuffer))
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
Buffer_U.Buffer[Buffer_U.Length/sizeof(WCHAR)] = L'\0';
bRc = !SetCurrentDirectoryW(Buffer_U.Buffer);
}
#endif
}
}
if (bRc)
{
if ((Rc = GetLastError()) == ERROR_NO_MEDIA_IN_DRIVE)
{
Rc = ERROR_NOT_READY;
}
}
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_chdrive: return %ld\n", Rc );
}
#endif
return(Rc);
}
ULONG
Od2Oem_chdir_chdrive(
LPSTR lpBuffer
)
/*++
Routine Description:
This routine changes the current working directory and the current drive
Arguments:
lpBuffer - path name of new working directory.
Return Value:
0 - OK.
non-zero - error.
Note:
Like : _chdrive(lpBuffer[0] - '@'); _chdir(lpBuffer);
If the directory is different from the current, it's set to the new one.
If the drive is different from the current, it's set to the new one.
--*/
{
UNICODE_STRING Buffer_U;
ANSI_STRING Buffer_A;
BOOL bRc;
ULONG Length, Rc = ERROR_NOT_ENOUGH_MEMORY;
WCHAR wBuffer[260];
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
WCHAR lpDriveName[] = L"=@:";
#else
CHAR lpDriveName[] = "=@:";
#endif
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_chdir_chdrive: for drive %c, (drive %ld), dir %s\n",
lpBuffer[0], Od2CurrentDisk, lpBuffer);
}
#endif
Or2InitMBString( &Buffer_A, lpBuffer);
if (!Or2MBStringToUnicodeString(&Buffer_U, &Buffer_A, TRUE))
{
Buffer_U.Buffer[Buffer_U.Length/sizeof(WCHAR)] = L'\0';
bRc = SetCurrentDirectoryW(Buffer_U.Buffer);
RtlFreeUnicodeString(&Buffer_U);
if (bRc)
{
if (!(Length = GetCurrentDirectoryW(260, wBuffer)) ||
(Length >= 260))
{
if (Length)
{
Rc = ERROR_NOT_ENOUGH_MEMORY;
} else
{
ASSERT(FALSE);
Rc = GetLastError();
}
} else
{
#if OS2SS_WIN32_GET_ENV_IN_UNICODE
lpDriveName[1] = wBuffer[0];
SetEnvironmentVariableW(lpDriveName, Buffer_U.Buffer);
#else
RtlInitUnicodeString( &Buffer_U, wBuffer );
Or2UnicodeStringToMBString (&Buffer_A, &Buffer_U, TRUE);
lpDriveName[1] = Buffer_A.Buffer[0];
SetEnvironmentVariableA(lpDriveName, Buffer_A.Buffer);
Or2FreeMBString(&Buffer_A);
#endif
}
Rc = 0;
} else
{
Rc = GetLastError();
}
}
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2Oem_chdir_chdrive: return %ld\n", Rc );
}
#endif
return(Rc);
}
VOID
Od2InitializeSearchHandleTable(
)
/*++
Routine Description:
This routine initializes the search handle table. Since it is not
inherited from the parent, we just mark each handle table entry free.
The table is initially statically allocated in the process's space.
If the number of find handles exceeds the space in the table, we allocate
a new table off the heap and copy the old one over.
The handle table is an array of pointers to search records.
Arguments:
none.
Return Value:
none.
--*/
{
ULONG i;
SearchHandleTable = SmallSearchHandleTable;
SearchHandleTableLength = INITIAL_SEARCH_HANDLES;
for (i=0;i<SearchHandleTableLength;i++) {
SearchHandleTable[i] = SEARCH_HANDLE_FREE;
}
}
APIRET
Od2InitializeFileSystemForExec(
ULONG ParentTableLength,
ULONG CurrentDrive
)
/*++
Routine Description:
This routine initializes the file system for an execpgm. This involves
allocating space and copying the file handle table and current directory
table from the parent process.
Arguments:
ParentTableLength - length of parent's file handle table. (number of entries)
CurrentDrive - parent's current drive
Return Value:
none.
--*/
{
OS2_API_MSG m;
POS2_COPYHANDLETABLE_MSG a = &m.u.CopyHandleTable;
PSTRING CurrentDirectoryString;
HANDLE CurDirHandle;
ULONG Length, i;
APIRET RetCode;
USHORT *Count;
PSZ RoutineName;
RoutineName = "Od2InitializeFileSystemForExec";
//
// initialize search handle table.
//
Od2InitializeSearchHandleTable();
//
// initialize current drive from parent value.
//
RetCode = Od2GetCurrentDirectory(CurrentDrive,
&CurrentDirectoryString,
&CurDirHandle,
&Length,
(BOOLEAN)FALSE
);
//
// since the process will die, we don't have to free any allocated
// heap space.
//
if (RetCode) {
return RetCode;
}
Od2CurrentDisk = CurrentDrive;
AllocateCurrentDirectory(CurrentDirectoryString,CurDirHandle);
RtlFreeHeap(Od2Heap,0,CurrentDirectoryString);
//
// if (table size != initial size)
// allocate heap
//
HandleTableLength = ParentTableLength;
if (HandleTableLength != INITIALFILEHANDLES) {
// allocate from child process's heap
HandleTable = RtlAllocateHeap(Od2Heap,0,HandleTableLength * sizeof(FILE_HANDLE));
}
else {
HandleTable = SmallHandleTable;
}
if (!HandleTable) {
#if DBG
KdPrint(("OS2: Od2InitializeFileSystemForExec out of heap memory, fail\n"));
#endif
ASSERT( FALSE );
return ERROR_NOT_ENOUGH_MEMORY;
}
// read table into memory
a->ChildHandleTable = HandleTable;
a->ChildTableLength = HandleTableLength;
RetCode = Od2CallSubsystem( &m, NULL, Oi2CopyHandleTable, sizeof( *a ) );
if (RetCode) {
return RetCode;
}
VerifyFlag = FALSE;
#if DBG
AcquireStdHandleLock(RoutineName);
#else
AcquireStdHandleLock();
#endif
for (i=0;i<HandleTableLength;i++)
{
if ((HandleTable[i].Flags & FILE_HANDLE_ALLOCATED) &&
(!(HandleTable[i].Flags & OPEN_FLAGS_NOINHERIT)))
{
if (HandleTable[i].IoVectorType == MonitorVectorType)
{
HandleTable[i].Flags = FILE_HANDLE_FREE;
} else if (HandleTable[i].IoVectorType == RemoteVectorType)
{
if (HandleTable[i].NtHandle == SesGrp->StdIn)
{
Count = &SesGrp->StdInHandleCount;
} else if (HandleTable[i].NtHandle == SesGrp->StdOut)
{
Count = &SesGrp->StdOutHandleCount;
} else if (HandleTable[i].NtHandle == SesGrp->StdErr)
{
Count = &SesGrp->StdErrHandleCount;
} else
Count = NULL;
if (Count && *Count) /* if legal and open */
{
(*Count)++; /* one more handle */
}
} else if (HandleTable[i].IoVectorType == MouseVectorType)
{
if (DevMouOpen(&(HandleTable[i].NtHandle)))
{
HandleTable[i].Flags = FILE_HANDLE_FREE;
}
}
else if ((HandleTable[i].IoVectorType == KbdVectorType) &&
!(HandleTable[i].DeviceAttribute & DEVICE_ATTRIBUTE_GENIOCTL))
{
// Logical KBD
KbdDupLogHandle(HandleTable[i].NtHandle);
}
// else if ((HandleTable[i].IoVectorType == ConVectorType) ||
// (HandleTable[i].IoVectorType == ScreenVectorType))
// {
// }
}
}
#if DBG
ReleaseStdHandleLock(RoutineName);
#else
ReleaseStdHandleLock();
#endif
return( m.ReturnedErrorValue );
}
NTSTATUS
GetFileAccess(
IN HFILE FileHandle,
IN OUT PULONG Access
)
/*++
Routine Description:
This routine returns the file access of a particular file
Arguments:
FileHandle - file handle of file to retrieve file access of
Access - where to store file access
Return Value:
none.
--*/
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
FILE_ACCESS_INFORMATION AccessInfo;
// this call requires no access
Status = NtQueryInformationFile(FileHandle,
&IoStatus,
&AccessInfo,
sizeof (AccessInfo),
FileAccessInformation);
if (!(NT_SUCCESS(Status))) {
return Status;
}
if (AccessInfo.AccessFlags & FILE_WRITE_DATA) {
if (AccessInfo.AccessFlags & FILE_READ_DATA) {
*Access |= OPEN_ACCESS_READWRITE;
}
else
*Access |= OPEN_ACCESS_WRITEONLY;
}
else
*Access |= OPEN_ACCESS_READONLY;
return STATUS_SUCCESS;
}
APIRET
Od2InitializeFileSystemForSM(
IN ULONG DefaultDrive,
IN HANDLE StandardInput,
IN HANDLE StandardOutput,
IN HANDLE StandardError
)
/*++
Routine Description:
This routine initializes the file system for the first time (when called
from the session manager). We initialize the file system variables -
the file handle table, current directory table, and verify flag and
set up handles 0-2 (stdin, stdout, stderr).
Arguments:
Return Value:
none.
--*/
{
int i;
NTSTATUS Status;
UNREFERENCED_PARAMETER(StandardInput);
UNREFERENCED_PARAMETER(StandardOutput);
UNREFERENCED_PARAMETER(StandardError);
//
// initialize search handle table.
//
Od2InitializeSearchHandleTable();
//
// initialize current disk to boot drive and current directory to
// root.
Status = Od2InitializeSessionDrives(
&Od2CurrentDisk
);
if ( !NT_SUCCESS( Status ) ) {
Od2CurrentDisk = DefaultDrive;
Od2CurrentDirectory.pCurDir = NULL;
Od2DirHandles[Od2CurrentDisk] = NULL;
Od2DirHandlesIsValid[Od2CurrentDisk] = TRUE;
}
// initialize file handle table.
HandleTable = SmallHandleTable;
HandleTableLength= INITIALFILEHANDLES;
for (i=0;i<INITIALFILEHANDLES;i++) {
HandleTable[i].Flags = FILE_HANDLE_FREE;
}
HandleTable[0].Flags = FILE_HANDLE_VALID | FILE_HANDLE_ALLOCATED | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY;
HandleTable[0].IoVectorType = RemoteVectorType;
HandleTable[0].NtHandle = SesGrp->StdIn;
HandleTable[0].DeviceAttribute = DEVICE_ATTRIBUTE_STDIN | DEVICE_ATTRIBUTE_STDOUT | DEVICE_ATTRIBUTE_CHAR | 0x80;
HandleTable[0].FileType = SesGrp->StdInFileType;
HandleTable[1].Flags = FILE_HANDLE_VALID | FILE_HANDLE_ALLOCATED | OPEN_SHARE_DENYNONE | OPEN_ACCESS_WRITEONLY;;
HandleTable[1].IoVectorType = RemoteVectorType;
HandleTable[1].NtHandle = SesGrp->StdOut;
HandleTable[1].DeviceAttribute = DEVICE_ATTRIBUTE_STDIN | DEVICE_ATTRIBUTE_STDOUT | DEVICE_ATTRIBUTE_CHAR | 0x80;
HandleTable[1].FileType = SesGrp->StdOutFileType;
HandleTable[2].Flags = FILE_HANDLE_VALID | FILE_HANDLE_ALLOCATED | OPEN_SHARE_DENYNONE | OPEN_ACCESS_WRITEONLY;;
HandleTable[2].IoVectorType = RemoteVectorType;
HandleTable[2].NtHandle = SesGrp->StdErr;
HandleTable[2].DeviceAttribute = DEVICE_ATTRIBUTE_STDIN | DEVICE_ATTRIBUTE_STDOUT | DEVICE_ATTRIBUTE_CHAR | 0x80;
HandleTable[2].FileType = SesGrp->StdErrFileType;
if (!SesGrp->StdInFlag)
{
HandleTable[0].DeviceAttribute = 0;
}
if (!SesGrp->StdOutFlag)
{
HandleTable[1].DeviceAttribute = 1;
}
if (!SesGrp->StdErrFlag)
{
HandleTable[2].DeviceAttribute = 2;
}
VerifyFlag = FALSE;
return NO_ERROR;
}
NTSTATUS
Od2InitializeSessionDrives(
OUT PULONG CurrentDisk
)
{
APIRET Rc = NO_ERROR;
CHAR S[260];
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitializeSessionDrives: disk %lu\n", *CurrentDisk);
}
#endif
if (Od2Oem_getcwd(S, 260))
{
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitializeSessionDrives: Od2Oem_getcwd failed, Rc %lu\n",
Rc);
}
#endif
*CurrentDisk = '\0';
} else
{
*CurrentDisk = (ULONG)(*S - 'A');
Rc = DosSetCurrentDir( S );
if (Rc)
{
#if DBG
ASSERT(FALSE);
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitializeSessionDrives: DosSetCurrentDrive failed, Rc %lu\n",
Rc);
}
#endif
}
}
return( Rc );
}
APIRET
Od2InitCurrentDir(
IN ULONG CurrentDisk
)
{
APIRET Rc;
CHAR S[260];
ULONG DefaultDrive;
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitCurrentDir: disk # %ld, Current %ld\n",
CurrentDisk, Od2CurrentDisk);
}
#endif
Od2Oem_getcwd(S, 260);
DefaultDrive = S[0] - '@';
if (!(Rc = Od2Oem_chdrive(CurrentDisk + 1)))
{
Rc = Od2Oem_getcwd(S, 260);
if (!Rc)
{
// There is a drive with valid directory name
Rc = DosSetCurrentDir( S );
} else
{
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitCurrentDir: Od2Oem_getcwd failed, Rc %lu\n",
Rc);
}
#endif
Rc = ERROR_NOT_READY;
}
Od2Oem_chdrive(DefaultDrive);
}
#if DBG
IF_OD2_DEBUG( FILESYS ) {
DbgPrint("Od2InitCurrentDir: return Rc %lu\n",
Rc);
}
#endif
return( Rc );
}
APIRET
Od2InitializeFileSystemForChildSM(
ULONG ParentTableLength,
ULONG CurrentDrive
)
/*++
Routine Description:
This routine initializes the file system for an execpgm. This involves
allocating space and copying the file handle table and current directory
table from the parent process.
Arguments:
ParentTableLength - length of parent's file handle table. (number of entries)
CurrentDrive - parent's current drive
Return Value:
none.
--*/
{
OS2_API_MSG m;
POS2_COPYHANDLETABLE_MSG a = &m.u.CopyHandleTable;
PSTRING CurrentDirectoryString;
HANDLE CurDirHandle;
ULONG Length, i;
APIRET RetCode;
USHORT *Count;
PSZ RoutineName;
RoutineName = "Od2InitializeFileSystemForChildSM";
//
// initialize search handle table.
//
Od2InitializeSearchHandleTable();
//
// initialize current drive from parent value.
//
Od2CurrentDisk = CurrentDrive+1;
//
// initialize current directory on current drive by calling server to
// retrieve it.
//
// we force GetCurrentDirectory to retrieve the currentdirectory from
// the server by passing in a drive guaranteed not to be the current drive -
// Od2CurrentDisk+1.
//
RetCode = Od2GetCurrentDirectory(CurrentDrive,
&CurrentDirectoryString,
&CurDirHandle,
&Length,
(BOOLEAN)FALSE
);
//
// since the process will die, we don't have to free any allocated
// heap space.
//
if (RetCode) {
return RetCode;
}
Od2CurrentDisk = CurrentDrive;
AllocateCurrentDirectory(CurrentDirectoryString,CurDirHandle);
RtlFreeHeap(Od2Heap,0,CurrentDirectoryString);
//
// if (table size != initial size)
// allocate heap
//
HandleTableLength = ParentTableLength;
if (HandleTableLength != INITIALFILEHANDLES) {
// allocate from child process's heap
HandleTable = RtlAllocateHeap(Od2Heap,0,HandleTableLength * sizeof(FILE_HANDLE));
}
else {
HandleTable = SmallHandleTable;
}
if (!HandleTable) {
#if DBG
KdPrint(("OS2: Od2InitializeFileSystemForChildSm out of heap memory, fail\n"));
#endif
ASSERT( FALSE );
return ERROR_NOT_ENOUGH_MEMORY;
}
// read table into memory
a->ChildHandleTable = HandleTable;
a->ChildTableLength = HandleTableLength;
RetCode = Od2CallSubsystem( &m, NULL, Oi2CopyHandleTable, sizeof( *a ) );
if (RetCode) {
return RetCode;
}
VerifyFlag = FALSE;
for (i=0;i<HandleTableLength;i++)
{
if ((HandleTable[i].Flags & FILE_HANDLE_ALLOCATED) &&
(!(HandleTable[i].Flags & OPEN_FLAGS_NOINHERIT)))
{
if (HandleTable[i].IoVectorType == MonitorVectorType)
{
HandleTable[i].Flags = FILE_HANDLE_FREE;
} else if (HandleTable[i].IoVectorType == RemoteVectorType)
{
if (HandleTable[i].NtHandle == SesGrp->StdIn)
{
Count = &SesGrp->StdInHandleCount;
} else if (HandleTable[i].NtHandle == SesGrp->StdOut)
{
Count = &SesGrp->StdOutHandleCount;
} else if (HandleTable[i].NtHandle == SesGrp->StdErr)
{
Count = &SesGrp->StdErrHandleCount;
} else
Count = NULL;
if (Count && *Count) /* if legal and open */
{
(*Count)++; /* one more handle */
}
} else if (HandleTable[i].IoVectorType == MouseVectorType)
{
if (DevMouOpen(&(HandleTable[i].NtHandle)))
{
HandleTable[i].Flags = FILE_HANDLE_FREE;
}
}
else if (HandleTable[i].IoVectorType == KbdVectorType)
{
if (!(HandleTable[i].DeviceAttribute & DEVICE_ATTRIBUTE_GENIOCTL))
{
// Physical Keybaord
HandleTable[i].NtHandle = (HANDLE)SesGrp->PhyKbd;
} else
{
// Logical KBD
if (KbdOpenLogHandle(&HandleTable[i].NtHandle))
HandleTable[i].Flags = FILE_HANDLE_FREE;
}
}
// else if ((HandleTable[i].IoVectorType == ConVectorType) ||
// (HandleTable[i].IoVectorType == ScreenVectorType))
// {
// }
}
}
/*
* if count=1, no one use this handle so it may be close
*/
if ((SesGrp->StdInHandleCount == 1) && !SesGrp->StdInFlag)
{
RemoteCloseHandle(SesGrp->StdIn);
}
if ((SesGrp->StdOutHandleCount == 1) && !SesGrp->StdOutFlag)
{
RemoteCloseHandle(SesGrp->StdOut);
}
if ((SesGrp->StdErrHandleCount == 1) && !SesGrp->StdErrFlag)
{
RemoteCloseHandle(SesGrp->StdErr);
}
return( m.ReturnedErrorValue );
}