[KERNEL32]: Fix build by fixing variables types.
[reactos.git] / reactos / dll / win32 / kernel32 / client / vdm.c
index 1f77268..81a42d3 100644 (file)
@@ -2,7 +2,7 @@
  * PROJECT:         ReactOS Win32 Base API
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            dll/win32/kernel32/client/vdm.c
- * PURPOSE:         Virtual Dos Machine (VDM) Support
+ * PURPOSE:         Virtual DOS Machines (VDM) Support
  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
  */
 
 
 /* TYPES **********************************************************************/
 
+typedef struct _ENV_INFO
+{
+    ULONG NameType;
+    ULONG NameLength;
+    PWCHAR Name;
+} ENV_INFO, *PENV_INFO;
+
+/* GLOBALS ********************************************************************/
+
+ENV_INFO BasepEnvNameType[] =
+{
+    {3, sizeof(L"PATH")      , L"PATH"      },
+    {2, sizeof(L"WINDIR")    , L"WINDIR"    },
+    {2, sizeof(L"SYSTEMROOT"), L"SYSTEMROOT"},
+    {3, sizeof(L"TEMP")      , L"TEMP"      },
+    {3, sizeof(L"TMP")       , L"TMP"       },
+};
+
+UNICODE_STRING BaseDotComSuffixName = RTL_CONSTANT_STRING(L".com");
+UNICODE_STRING BaseDotPifSuffixName = RTL_CONSTANT_STRING(L".pif");
+UNICODE_STRING BaseDotExeSuffixName = RTL_CONSTANT_STRING(L".exe");
+
 /* FUNCTIONS ******************************************************************/
 
+ULONG
+WINAPI
+BaseIsDosApplication(IN PUNICODE_STRING PathName,
+                     IN NTSTATUS Status)
+{
+    UNICODE_STRING String;
+
+    /* Is it a .com? */
+    String.Length = BaseDotComSuffixName.Length;
+    String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
+    if (RtlEqualUnicodeString(&String, &BaseDotComSuffixName, TRUE)) return BINARY_TYPE_COM;
+
+    /* Is it a .pif? */
+    String.Length = BaseDotPifSuffixName.Length;
+    String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
+    if (RtlEqualUnicodeString(&String, &BaseDotPifSuffixName, TRUE)) return BINARY_TYPE_PIF;
+
+    /* Is it an exe? */
+    String.Length = BaseDotExeSuffixName.Length;
+    String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
+    if (RtlEqualUnicodeString(&String, &BaseDotExeSuffixName, TRUE)) return BINARY_TYPE_EXE;
+
+    return 0;
+}
+
+BOOL
+WINAPI
+BaseCheckVDM(IN ULONG BinaryType,
+             IN PCWCH ApplicationName,
+             IN PCWCH CommandLine,
+             IN PCWCH CurrentDirectory,
+             IN PANSI_STRING AnsiEnvironment,
+             IN PBASE_API_MESSAGE ApiMessage,
+             IN OUT PULONG iTask,
+             IN DWORD CreationFlags,
+             IN LPSTARTUPINFOW StartupInfo,
+             IN HANDLE hUserToken OPTIONAL)
+{
+    /* This is not supported */
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
+BOOL
+WINAPI
+BaseUpdateVDMEntry(IN ULONG UpdateIndex,
+                   IN OUT PHANDLE WaitHandle,
+                   IN ULONG IndexInfo,
+                   IN ULONG BinaryType)
+{
+#if 0 // Unimplemented in BASESRV
+    NTSTATUS Status;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_UPDATE_VDM_ENTRY UpdateVdmEntry = &ApiMessage.Data.UpdateVdmEntry;
+
+    /* Check what update is being sent */
+    switch (UpdateIndex)
+    {
+        /* VDM is being undone */
+        case VdmEntryUndo:
+        {
+            /* Tell the server how far we had gotten along */
+            UpdateVdmEntry->iTask = HandleToUlong(*WaitHandle);
+            UpdateVdmEntry->VDMCreationState = IndexInfo;
+            break;
+        }
+
+        /* VDM is ready with a new process handle */
+        case VdmEntryUpdateProcess:
+        {
+            /* Send it the process handle */
+            UpdateVdmEntry->VDMProcessHandle = *WaitHandle;
+            UpdateVdmEntry->iTask = IndexInfo;
+            break;
+        }
+    }
+
+    /* Also check what kind of binary this is for the console handle */
+    if (BinaryType == BINARY_TYPE_WOW)
+    {
+        /* Magic value for 16-bit apps */
+        UpdateVdmEntry->ConsoleHandle = (HANDLE)-1;
+    }
+    else if (UpdateVdmEntry->iTask)
+    {
+        /* No handle for true VDM */
+        UpdateVdmEntry->ConsoleHandle = NULL;
+    }
+    else
+    {
+        /* Otherwise, use the regular console handle */
+        UpdateVdmEntry->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    }
+
+    /* Finally write the index and binary type */
+    UpdateVdmEntry->EntryIndex = UpdateIndex;
+    UpdateVdmEntry->BinaryType = BinaryType;
+
+    /* Send the message to CSRSS */
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                                 NULL,
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepUpdateVDMEntry),
+                                 sizeof(BASE_UPDATE_VDM_ENTRY));
+    if (!NT_SUCCESS(Status))
+    {
+        /* Handle failure */
+        BaseSetLastNTError(Status);
+        return FALSE;
+    }
+
+    /* If this was an update, CSRSS returns a new wait handle */
+    if (UpdateIndex == VdmEntryUpdateProcess)
+    {
+        /* Return it to the caller */
+        *WaitHandle = UpdateVdmEntry->WaitObjectForParent;
+    }
+#endif
+    /* We made it */
+    return TRUE;
+}
+
+BOOL
+WINAPI
+BaseCheckForVDM(IN HANDLE ProcessHandle,
+                OUT LPDWORD ExitCode)
+{
+#if 0 // Unimplemented in BASESRV
+    NTSTATUS Status;
+    EVENT_BASIC_INFORMATION EventBasicInfo;
+    BASE_API_MESSAGE ApiMessage;
+    PBASE_GET_VDM_EXIT_CODE GetVdmExitCode = &ApiMessage.Data.GetVdmExitCode;
+
+    /* It's VDM if the process is actually a wait handle (an event) */
+    Status = NtQueryEvent(ProcessHandle,
+                          EventBasicInformation,
+                          &EventBasicInfo,
+                          sizeof(EventBasicInfo),
+                          NULL);
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Setup the input parameters */
+    GetVdmExitCode->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    GetVdmExitCode->hParent = ProcessHandle;
+
+    /* Call CSRSS */
+    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                                 NULL,
+                                 CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetVDMExitCode),
+                                 sizeof(BASE_GET_VDM_EXIT_CODE));
+    if (!NT_SUCCESS(Status)) return FALSE;
+
+    /* Get the exit code from the reply */
+    *ExitCode = GetVdmExitCode->ExitCode;
+#endif
+    return TRUE;
+}
+
+BOOL
+WINAPI
+BaseGetVdmConfigInfo(IN LPCWSTR CommandLineReserved,
+                     IN ULONG DosSeqId,
+                     IN ULONG BinaryType,
+                     IN PUNICODE_STRING CmdLineString,
+                     OUT PULONG VdmSize)
+{
+    WCHAR Buffer[MAX_PATH];
+    WCHAR CommandLine[MAX_PATH * 2];
+    ULONG Length;
+
+    /* Clear the buffer in case we fail */
+    CmdLineString->Buffer = 0;
+
+    /* Always return the same size: 16 Mb */
+    *VdmSize = 0x1000000;
+
+    /* Get the system directory */
+    Length = GetSystemDirectoryW(Buffer, MAX_PATH);
+    if (!(Length) || (Length >= MAX_PATH))
+    {
+        /* Eliminate no path or path too big */
+        SetLastError(ERROR_INVALID_NAME);
+        return FALSE;
+    }
+
+    /* Check if this is VDM with a DOS Sequence ID */
+    if (DosSeqId)
+    {
+        /*
+         * Build the VDM string for it:
+         * -i%lx : Gives the DOS Sequence ID;
+         * %s%c  : Nothing if DOS VDM, -w if WoW VDM, -ws if separate WoW VDM.
+         */
+        _snwprintf(CommandLine,
+                   sizeof(CommandLine),
+                   L"\"%s\\ntvdm.exe\" -i%lx %s%c",
+                   Buffer,
+                   DosSeqId,
+                   (BinaryType == BINARY_TYPE_DOS) ? L" " : L"-w",
+                   (BinaryType == BINARY_TYPE_SEPARATE_WOW) ? L's' : L' ');
+    }
+    else
+    {
+        /*
+         * Build the string for it without the DOS Sequence ID:
+         * %s%c  : Nothing if DOS VDM, -w if WoW VDM, -ws if separate WoW VDM.
+         */
+        _snwprintf(CommandLine,
+                   sizeof(CommandLine),
+                   L"\"%s\\ntvdm.exe\" %s%c",
+                   Buffer,
+                   (BinaryType == BINARY_TYPE_DOS) ? L" " : L"-w",
+                   (BinaryType == BINARY_TYPE_SEPARATE_WOW) ? L's' : L' ');
+    }
+
+    /* Create the actual string */
+    return RtlCreateUnicodeString(CmdLineString, CommandLine);
+}
+
+UINT
+WINAPI
+BaseGetEnvNameType_U(IN PWCHAR Name,
+                     IN ULONG NameLength)
+{
+    PENV_INFO EnvInfo;
+    ULONG NameType, i;
+
+    /* Start by assuming unknown type */
+    NameType = 1;
+
+    /* Loop all the environment names */
+    for (i = 0; i < (sizeof(BasepEnvNameType) / sizeof(ENV_INFO)); i++)
+    {
+        /* Get this entry */
+        EnvInfo = &BasepEnvNameType[i];
+
+        /* Check if it matches the name */
+        if ((EnvInfo->NameLength == NameLength) &&
+            !(_wcsnicmp(EnvInfo->Name, Name, NameLength)))
+        {
+            /* It does, return the type */
+            NameType = EnvInfo->NameType;
+            break;
+        }
+    }
+
+    /* Return what we found, or unknown if nothing */
+    return NameType;
+}
+
+BOOL
+NTAPI
+BaseDestroyVDMEnvironment(IN PANSI_STRING AnsiEnv,
+                          IN PUNICODE_STRING UnicodeEnv)
+{
+    ULONG Dummy = 0;
+
+    /* Clear the ASCII buffer since Rtl creates this for us */
+    if (AnsiEnv->Buffer) RtlFreeAnsiString(AnsiEnv);
+
+    /* The Unicode buffer is build by hand, though */
+    if (UnicodeEnv->Buffer)
+    {
+        /* So clear it through the API */
+        NtFreeVirtualMemory(NtCurrentProcess(),
+                            (PVOID*)&UnicodeEnv->Buffer,
+                            &Dummy,
+                            MEM_RELEASE);
+    }
+
+    /* All done */
+    return TRUE;
+}
+
+BOOL
+NTAPI
+BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
+                         IN PANSI_STRING AnsiEnv,
+                         IN PUNICODE_STRING UnicodeEnv)
+{
+    BOOL Result;
+    ULONG RegionSize, EnvironmentSize = 0;
+    PWCHAR p, Environment, NewEnvironment = NULL;
+    NTSTATUS Status;
+
+    /* Make sure we have both strings */
+    if (!(AnsiEnv) || !(UnicodeEnv))
+    {
+        /* Fail */
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* Check if an environment was passed in */
+    if (!lpEnvironment)
+    {
+        /* Nope, create one */
+        Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
+        if (!NT_SUCCESS(Status)) goto Quickie;
+    }
+    else
+    {
+        /* Use the one we got */
+        Environment = lpEnvironment;
+    }
+
+    /* Do we have something now ? */
+    if (!Environment)
+    {
+        /* Still not, fail out */
+        SetLastError(ERROR_BAD_ENVIRONMENT);
+        goto Quickie;
+    }
+
+    /* Count how much space the whole environment takes */
+    p = Environment;
+    while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
+    EnvironmentSize += sizeof(UNICODE_NULL);
+
+    /* Allocate a new copy */
+    RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
+    if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
+                                            (PVOID*)&NewEnvironment,
+                                            0,
+                                            &RegionSize,
+                                            MEM_COMMIT,
+                                            PAGE_READWRITE)))
+    {
+        /* We failed, bail out */
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        NewEnvironment = NULL;
+        goto Quickie;
+    }
+
+    /* Begin parsing the new environment */
+    p = NewEnvironment;
+
+    /* FIXME: Code here */
+
+    /* Terminate it */
+    *p++ = UNICODE_NULL;
+
+    /* Initialize the unicode string to hold it */
+    EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
+    RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, (USHORT)EnvironmentSize);
+    UnicodeEnv->Length = (USHORT)EnvironmentSize;
+
+    /* Create the ASCII version of it */
+    Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Set last error if conversion failure */
+        BaseSetLastNTError(Status);
+    }
+    else
+    {
+        /* Everything went okay, so return success */
+        Result = TRUE;
+        NewEnvironment = NULL;
+    }
+
+Quickie:
+    /* Cleanup path starts here, start by destroying the envrionment copy */
+    if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);
+
+    /* See if we are here due to failure */
+    if (NewEnvironment)
+    {
+        /* Initialize the paths to be empty */
+        RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
+        RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);
+
+        /* Free the environment copy */
+        RegionSize = 0;
+        Status = NtFreeVirtualMemory(NtCurrentProcess(),
+                                     (PVOID*)&NewEnvironment,
+                                     &RegionSize,
+                                     MEM_RELEASE);
+        ASSERT(NT_SUCCESS(Status));
+    }
+
+    /* Return the result */
+    return Result;
+}
+
 
 /* Check whether a file is an OS/2 or a very old Windows executable
  * by testing on import of KERNEL.
@@ -287,7 +693,7 @@ GetBinaryTypeW (
     }
   }
 
-  DPRINT1("Invalid binary type returned!\n", BinType);
+  DPRINT1("Invalid binary type %lu returned!\n", BinType);
   return FALSE;
 }