ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

vdm.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Win32 Base API
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            dll/win32/kernel32/client/vdm.c
00005  * PURPOSE:         Virtual Dos Machine (VDM) Support
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include <k32.h>
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* TYPES **********************************************************************/
00017 
00018 typedef struct _ENV_INFO
00019 {
00020     ULONG NameType;
00021     ULONG NameLength;
00022     PWCHAR Name;
00023 } ENV_INFO, *PENV_INFO;
00024 
00025 /* GLOBALS ********************************************************************/
00026 
00027 ENV_INFO BasepEnvNameType[] =
00028 {
00029     {3, sizeof(L"PATH"), L"PATH"},
00030     {2, sizeof(L"WINDIR"), L"WINDIR"},
00031     {2, sizeof(L"SYSTEMROOT"), L"SYSTEMROOT"},
00032     {3, sizeof(L"TEMP"), L"TEMP"},
00033     {3, sizeof(L"TMP"), L"TMP"},
00034 };
00035 
00036 UNICODE_STRING BaseDotComSuffixName = RTL_CONSTANT_STRING(L".com");
00037 UNICODE_STRING BaseDotPifSuffixName = RTL_CONSTANT_STRING(L".pif");
00038 UNICODE_STRING BaseDotExeSuffixName = RTL_CONSTANT_STRING(L".exe");
00039 
00040 /* FUNCTIONS ******************************************************************/
00041 
00042 ULONG
00043 WINAPI
00044 BaseIsDosApplication(IN PUNICODE_STRING PathName,
00045                      IN NTSTATUS Status)
00046 {
00047     UNICODE_STRING String;
00048 
00049     /* Is it a .com? */
00050     String.Length = BaseDotComSuffixName.Length;
00051     String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
00052     if (RtlEqualUnicodeString(&String, &BaseDotComSuffixName, TRUE)) return 2;
00053 
00054     /* Is it a .pif? */
00055     String.Length = BaseDotPifSuffixName.Length;
00056     String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
00057     if (RtlEqualUnicodeString(&String, &BaseDotPifSuffixName, TRUE)) return 3;
00058 
00059     /* Is it an exe? */
00060     String.Length = BaseDotExeSuffixName.Length;
00061     String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
00062     if (RtlEqualUnicodeString(&String, &BaseDotExeSuffixName, TRUE)) return 1;
00063     return 0;
00064 }
00065 
00066 BOOL
00067 WINAPI
00068 BaseCheckVDM(IN ULONG BinaryType,
00069              IN PCWCH ApplicationName,
00070              IN PCWCH CommandLine,
00071              IN PCWCH CurrentDirectory,
00072              IN PANSI_STRING AnsiEnvironment,
00073              IN PCSR_API_MESSAGE Msg,
00074              IN OUT PULONG iTask,
00075              IN DWORD CreationFlags,
00076              IN LPSTARTUPINFOW StartupInfo)
00077 {
00078     /* This is not supported */
00079     UNIMPLEMENTED;
00080     return FALSE;
00081 }
00082 
00083 BOOL
00084 WINAPI
00085 BaseUpdateVDMEntry(IN ULONG UpdateIndex,
00086                    IN OUT PHANDLE WaitHandle,
00087                    IN ULONG IndexInfo,
00088                    IN ULONG BinaryType)
00089 {
00090     NTSTATUS Status;
00091     CSR_API_MESSAGE Msg;
00092     ULONG CsrRequest = MAKE_CSR_API(UPDATE_VDM_ENTRY, CSR_CONSOLE);
00093 
00094     /* Check what update is being sent */
00095     switch (UpdateIndex)
00096     {
00097         /* VDM is being undone */
00098         case VdmEntryUndo:
00099 
00100             /* Tell the server how far we had gotten along */
00101             Msg.Data.UpdateVdmEntry.iTask = (ULONG)*WaitHandle;
00102             Msg.Data.UpdateVdmEntry.VDMCreationState = IndexInfo;
00103             break;
00104 
00105         /* VDM is ready with a new process handle */
00106         case VdmEntryUpdateProcess:
00107 
00108             /* Send it the process handle */
00109             Msg.Data.UpdateVdmEntry.VDMProcessHandle = *WaitHandle;
00110             Msg.Data.UpdateVdmEntry.iTask = IndexInfo;
00111             break;
00112     }
00113 
00114     /* Also check what kind of binary this is for the console handle */
00115     if (BinaryType == BINARY_TYPE_WOW)
00116     {
00117         /* Magic value for 16-bit apps */
00118         Msg.Data.UpdateVdmEntry.ConsoleHandle = (HANDLE)-1;
00119     }
00120     else if (Msg.Data.UpdateVdmEntry.iTask)
00121     {
00122         /* No handle for true VDM */
00123         Msg.Data.UpdateVdmEntry.ConsoleHandle = 0;
00124     }
00125     else
00126     {
00127         /* Otherwise, send the regular consoel handle */
00128         Msg.Data.UpdateVdmEntry.ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
00129     }
00130 
00131     /* Finally write the index and binary type */
00132     Msg.Data.UpdateVdmEntry.EntryIndex = UpdateIndex;
00133     Msg.Data.UpdateVdmEntry.BinaryType = BinaryType;
00134 
00135     /* Send the message to CSRSS */
00136     Status = CsrClientCallServer(&Msg, NULL, CsrRequest, sizeof(Msg));
00137     if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(Msg.Status)))
00138     {
00139         /* Handle failure */
00140         BaseSetLastNTError(Msg.Status);
00141         return FALSE;
00142     }
00143 
00144     /* If this was an update, CSRSS returns a new wait handle */
00145     if (UpdateIndex == VdmEntryUpdateProcess)
00146     {
00147         /* Return it to the caller */
00148         *WaitHandle = Msg.Data.UpdateVdmEntry.WaitObjectForParent;
00149     }
00150 
00151     /* We made it */
00152     return TRUE;
00153 }
00154 
00155 BOOL
00156 WINAPI
00157 BaseCheckForVDM(IN HANDLE ProcessHandle,
00158                 OUT LPDWORD ExitCode)
00159 {
00160     NTSTATUS Status;
00161     EVENT_BASIC_INFORMATION EventBasicInfo;
00162     CSR_API_MESSAGE Msg;
00163     ULONG CsrRequest = MAKE_CSR_API(GET_VDM_EXIT_CODE, CSR_CONSOLE);
00164 
00165     /* It's VDM if the process is actually a wait handle (an event) */
00166     Status = NtQueryEvent(ProcessHandle,
00167                           EventBasicInformation,
00168                           &EventBasicInfo,
00169                           sizeof(EventBasicInfo),
00170                           NULL);
00171     if (!NT_SUCCESS(Status)) return FALSE;
00172 
00173     /* Setup the input parameters */
00174     Msg.Data.GetVdmExitCode.ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
00175     Msg.Data.GetVdmExitCode.hParent = ProcessHandle;
00176 
00177     /* Call CSRSS */
00178     Status = CsrClientCallServer(&Msg, NULL, CsrRequest, sizeof(Msg));
00179     if (!NT_SUCCESS(Status)) return FALSE;
00180 
00181     /* Get the exit code from the reply */
00182     *ExitCode = Msg.Data.GetVdmExitCode.ExitCode;
00183     return TRUE;
00184 }
00185 
00186 BOOL
00187 WINAPI
00188 BaseGetVdmConfigInfo(IN LPCWSTR Reserved,
00189                      IN ULONG DosSeqId,
00190                      IN ULONG BinaryType,
00191                      IN PUNICODE_STRING CmdLineString,
00192                      OUT PULONG VdmSize)
00193 {
00194     WCHAR Buffer[MAX_PATH];
00195     WCHAR CommandLine[MAX_PATH * 2];
00196     ULONG Length;
00197 
00198     /* Clear the buffer in case we fail */
00199     CmdLineString->Buffer = 0;
00200 
00201     /* Always return the same size */
00202     *VdmSize = 0x1000000;
00203 
00204     /* Get the system directory */
00205     Length = GetSystemDirectoryW(Buffer, MAX_PATH);
00206     if (!(Length) || (Length >= MAX_PATH))
00207     {
00208         /* Eliminate no path or path too big */
00209         SetLastError(ERROR_INVALID_NAME);
00210         return FALSE;
00211     }
00212 
00213     /* Check if this is VDM with a DOS Sequence ID */
00214     if (DosSeqId)
00215     {
00216         /* Build the VDM string for it */
00217         _snwprintf(CommandLine,
00218                    sizeof(CommandLine),
00219                    L"\"%s\\ntvdm.exe\" -i%lx %s%c",
00220                    Buffer,
00221                    DosSeqId,
00222                    (BinaryType == 0x10) ? L" " : L"-w",
00223                    (BinaryType == 0x40) ? 's' : ' ');
00224     }
00225     else
00226     {
00227         /* Non-DOS, build the stirng for it without the task ID */
00228         _snwprintf(CommandLine,
00229                    sizeof(CommandLine),
00230                    L"\"%s\\ntvdm.exe\"  %s%c",
00231                    Buffer,
00232                    (BinaryType == 0x10) ? L" " : L"-w",
00233                    (BinaryType == 0x40) ? 's' : ' ');
00234     }
00235 
00236     /* Create the actual string */
00237     return RtlCreateUnicodeString(CmdLineString, CommandLine);
00238 }
00239 
00240 UINT
00241 WINAPI
00242 BaseGetEnvNameType_U(IN PWCHAR Name,
00243                      IN ULONG NameLength)
00244 {
00245     PENV_INFO EnvInfo;
00246     ULONG NameType, i;
00247 
00248     /* Start by assuming unknown type */
00249     NameType = 1;
00250 
00251     /* Loop all the environment names */
00252     for (i = 0; i < (sizeof(BasepEnvNameType) / sizeof(ENV_INFO)); i++)
00253     {
00254         /* Get this entry */
00255         EnvInfo = &BasepEnvNameType[i];
00256 
00257         /* Check if it matches the name */
00258         if ((EnvInfo->NameLength == NameLength) &&
00259             !(_wcsnicmp(EnvInfo->Name, Name, NameLength)))
00260         {
00261             /* It does, return the type */
00262             NameType = EnvInfo->NameType;
00263             break;
00264         }
00265     }
00266 
00267     /* Return what we found, or unknown if nothing */
00268     return NameType;
00269 }
00270 
00271 BOOL
00272 NTAPI
00273 BaseDestroyVDMEnvironment(IN PANSI_STRING AnsiEnv,
00274                           IN PUNICODE_STRING UnicodeEnv)
00275 {
00276     ULONG Dummy = 0;
00277 
00278     /* Clear the ASCII buffer since Rtl creates this for us */
00279     if (AnsiEnv->Buffer) RtlFreeAnsiString(AnsiEnv);
00280 
00281     /* The Unicode buffer is build by hand, though */
00282     if (UnicodeEnv->Buffer)
00283     {
00284         /* So clear it through the API */
00285         NtFreeVirtualMemory(NtCurrentProcess(),
00286                             (PVOID*)&UnicodeEnv->Buffer,
00287                             &Dummy,
00288                             MEM_RELEASE);
00289     }
00290 
00291     /* All done */
00292     return TRUE;
00293 }
00294 
00295 BOOL
00296 NTAPI
00297 BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
00298                          IN PANSI_STRING AnsiEnv,
00299                          IN PUNICODE_STRING UnicodeEnv)
00300 {
00301     BOOL Result;
00302     ULONG RegionSize, EnvironmentSize = 0;
00303     PWCHAR p, Environment, NewEnvironment;
00304     NTSTATUS Status;
00305 
00306     /* Make sure we have both strings */
00307     if (!(AnsiEnv) || !(UnicodeEnv))
00308     {
00309         /* Fail */
00310         SetLastError(ERROR_INVALID_PARAMETER);
00311         return FALSE;
00312     }
00313 
00314     /* Check if an environment was passed in */
00315     if (!lpEnvironment)
00316     {
00317         /* Nope, create one */
00318         Status = RtlCreateEnvironment(TRUE, (PWCHAR*)&Environment);
00319         if (!NT_SUCCESS(Status)) goto Quickie;
00320     }
00321     else
00322     {
00323         /* Use the one we got */
00324         Environment = lpEnvironment;
00325     }
00326 
00327     /* Do we have something now ? */
00328     if (!Environment)
00329     {
00330         /* Still not, fail out */
00331         SetLastError(ERROR_BAD_ENVIRONMENT);
00332         goto Quickie;
00333     }
00334 
00335     /* Count how much space the whole environment takes */
00336     p = Environment;
00337     while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
00338     EnvironmentSize += sizeof(UNICODE_NULL);
00339 
00340     /* Allocate a new copy */
00341     RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
00342     if (!NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(),
00343                                             (PVOID*)&NewEnvironment,
00344                                             0,
00345                                             &RegionSize,
00346                                             MEM_COMMIT,
00347                                             PAGE_READWRITE)))
00348     {
00349         /* We failed, bail out */
00350         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00351         NewEnvironment = NULL;
00352         goto Quickie;
00353     }
00354 
00355     /* Begin parsing the new environment */
00356     p = NewEnvironment;
00357 
00358     /* FIXME: Code here */
00359 
00360     /* Terminate it */
00361     *p++ = UNICODE_NULL;
00362 
00363     /* Initialize the unicode string to hold it */
00364     EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
00365     RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, EnvironmentSize);
00366     UnicodeEnv->Length = EnvironmentSize;
00367 
00368     /* Create the ASCII version of it */
00369     Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
00370     if (!NT_SUCCESS(Status))
00371     {
00372         /* Set last error if conversion failure */
00373         BaseSetLastNTError(Status);
00374     }
00375     else
00376     {
00377         /* Everything went okay, so return success */
00378         Result = TRUE;
00379         NewEnvironment = NULL;
00380     }
00381 
00382 Quickie:
00383     /* Cleanup path starts here, start by destroying the envrionment copy */
00384     if (!(lpEnvironment) && (Environment)) RtlDestroyEnvironment(Environment);
00385 
00386     /* See if we are here due to failure */
00387     if (NewEnvironment)
00388     {
00389         /* Initialize the paths to be empty */
00390         RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
00391         RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);
00392 
00393         /* Free the environment copy */
00394         RegionSize = 0;
00395         Status = NtFreeVirtualMemory(NtCurrentProcess(),
00396                                      (PVOID*)&NewEnvironment,
00397                                      &RegionSize,
00398                                      MEM_RELEASE);
00399         ASSERT(NT_SUCCESS(Status));
00400     }
00401 
00402     /* Return the result */
00403     return Result;
00404 }
00405 
00406 
00407 /* Check whether a file is an OS/2 or a very old Windows executable
00408  * by testing on import of KERNEL.
00409  *
00410  * FIXME: is reading the module imports the only way of discerning
00411  *        old Windows binaries from OS/2 ones ? At least it seems so...
00412  */
00413 static DWORD WINAPI
00414 InternalIsOS2OrOldWin(HANDLE hFile, IMAGE_DOS_HEADER *mz, IMAGE_OS2_HEADER *ne)
00415 {
00416   DWORD CurPos;
00417   LPWORD modtab = NULL;
00418   LPSTR nametab = NULL;
00419   DWORD Read, Ret;
00420   int i;
00421 
00422   Ret = BINARY_OS216;
00423   CurPos = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
00424 
00425   /* read modref table */
00426   if((SetFilePointer(hFile, mz->e_lfanew + ne->ne_modtab, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) ||
00427      (!(modtab = HeapAlloc(GetProcessHeap(), 0, ne->ne_cmod * sizeof(WORD)))) ||
00428      (!(ReadFile(hFile, modtab, ne->ne_cmod * sizeof(WORD), &Read, NULL))) ||
00429      (Read != (DWORD)ne->ne_cmod * sizeof(WORD)))
00430   {
00431     goto broken;
00432   }
00433 
00434   /* read imported names table */
00435   if((SetFilePointer(hFile, mz->e_lfanew + ne->ne_imptab, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) ||
00436      (!(nametab = HeapAlloc(GetProcessHeap(), 0, ne->ne_enttab - ne->ne_imptab))) ||
00437      (!(ReadFile(hFile, nametab, ne->ne_enttab - ne->ne_imptab, &Read, NULL))) ||
00438      (Read != (DWORD)ne->ne_enttab - ne->ne_imptab))
00439   {
00440     goto broken;
00441   }
00442 
00443   for(i = 0; i < ne->ne_cmod; i++)
00444   {
00445     LPSTR module;
00446     module = &nametab[modtab[i]];
00447     if(!strncmp(&module[1], "KERNEL", module[0]))
00448     {
00449       /* very old windows file */
00450       Ret = BINARY_WIN16;
00451       goto done;
00452     }
00453   }
00454 
00455   broken:
00456   DPRINT1("InternalIsOS2OrOldWin(): Binary file seems to be broken\n");
00457 
00458   done:
00459   HeapFree(GetProcessHeap(), 0, modtab);
00460   HeapFree(GetProcessHeap(), 0, nametab);
00461   SetFilePointer(hFile, CurPos, NULL, FILE_BEGIN);
00462   return Ret;
00463 }
00464 
00465 static DWORD WINAPI
00466 InternalGetBinaryType(HANDLE hFile)
00467 {
00468   union
00469   {
00470     struct
00471     {
00472       unsigned char magic[4];
00473       unsigned char ignored[12];
00474       unsigned short type;
00475     } elf;
00476     struct
00477     {
00478       unsigned long magic;
00479       unsigned long cputype;
00480       unsigned long cpusubtype;
00481       unsigned long filetype;
00482     } macho;
00483     IMAGE_DOS_HEADER mz;
00484   } Header;
00485   char magic[4];
00486   DWORD Read;
00487 
00488   if((SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) ||
00489      (!ReadFile(hFile, &Header, sizeof(Header), &Read, NULL) ||
00490       (Read != sizeof(Header))))
00491   {
00492     return BINARY_UNKNOWN;
00493   }
00494 
00495   if(!memcmp(Header.elf.magic, "\177ELF", sizeof(Header.elf.magic)))
00496   {
00497     /* FIXME: we don't bother to check byte order, architecture, etc. */
00498     switch(Header.elf.type)
00499     {
00500       case 2:
00501         return BINARY_UNIX_EXE;
00502       case 3:
00503         return BINARY_UNIX_LIB;
00504     }
00505     return BINARY_UNKNOWN;
00506   }
00507 
00508   /* Mach-o File with Endian set to Big Endian  or Little Endian*/
00509   if(Header.macho.magic == 0xFEEDFACE ||
00510      Header.macho.magic == 0xCEFAEDFE)
00511   {
00512     switch(Header.macho.filetype)
00513     {
00514       case 0x8:
00515         /* MH_BUNDLE */
00516         return BINARY_UNIX_LIB;
00517     }
00518     return BINARY_UNKNOWN;
00519   }
00520 
00521   /* Not ELF, try DOS */
00522   if(Header.mz.e_magic == IMAGE_DOS_SIGNATURE)
00523   {
00524     /* We do have a DOS image so we will now try to seek into
00525      * the file by the amount indicated by the field
00526      * "Offset to extended header" and read in the
00527      * "magic" field information at that location.
00528      * This will tell us if there is more header information
00529      * to read or not.
00530      */
00531     if((SetFilePointer(hFile, Header.mz.e_lfanew, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) ||
00532        (!ReadFile(hFile, magic, sizeof(magic), &Read, NULL) ||
00533         (Read != sizeof(magic))))
00534     {
00535       return BINARY_DOS;
00536     }
00537 
00538     /* Reading the magic field succeeded so
00539      * we will try to determine what type it is.
00540      */
00541     if(!memcmp(magic, "PE\0\0", sizeof(magic)))
00542     {
00543       IMAGE_FILE_HEADER FileHeader;
00544       if(!ReadFile(hFile, &FileHeader, sizeof(IMAGE_FILE_HEADER), &Read, NULL) ||
00545          (Read != sizeof(IMAGE_FILE_HEADER)))
00546       {
00547         return BINARY_DOS;
00548       }
00549 
00550       /* FIXME - detect 32/64 bit */
00551 
00552       if(FileHeader.Characteristics & IMAGE_FILE_DLL)
00553         return BINARY_PE_DLL32;
00554       return BINARY_PE_EXE32;
00555     }
00556 
00557     if(!memcmp(magic, "NE", 1))
00558     {
00559       /* This is a Windows executable (NE) header.  This can
00560        * mean either a 16-bit OS/2 or a 16-bit Windows or even a
00561        * DOS program (running under a DOS extender).  To decide
00562        * which, we'll have to read the NE header.
00563        */
00564       IMAGE_OS2_HEADER ne;
00565       if((SetFilePointer(hFile, Header.mz.e_lfanew, NULL, FILE_BEGIN) == 1) ||
00566          !ReadFile(hFile, &ne, sizeof(IMAGE_OS2_HEADER), &Read, NULL) ||
00567          (Read != sizeof(IMAGE_OS2_HEADER)))
00568       {
00569         /* Couldn't read header, so abort. */
00570         return BINARY_DOS;
00571       }
00572 
00573       switch(ne.ne_exetyp)
00574       {
00575         case 2:
00576           return BINARY_WIN16;
00577         case 5:
00578           return BINARY_DOS;
00579         default:
00580           return InternalIsOS2OrOldWin(hFile, &Header.mz, &ne);
00581       }
00582     }
00583     return BINARY_DOS;
00584   }
00585   return BINARY_UNKNOWN;
00586 }
00587 
00588 /*
00589  * @implemented
00590  */
00591 BOOL
00592 WINAPI
00593 GetBinaryTypeW (
00594     LPCWSTR lpApplicationName,
00595     LPDWORD lpBinaryType
00596     )
00597 {
00598   HANDLE hFile;
00599   DWORD BinType;
00600 
00601   if(!lpApplicationName || !lpBinaryType)
00602   {
00603     SetLastError(ERROR_INVALID_PARAMETER);
00604     return FALSE;
00605   }
00606 
00607   hFile = CreateFileW(lpApplicationName, GENERIC_READ, FILE_SHARE_READ, NULL,
00608                       OPEN_EXISTING, 0, 0);
00609   if(hFile == INVALID_HANDLE_VALUE)
00610   {
00611     return FALSE;
00612   }
00613 
00614   BinType = InternalGetBinaryType(hFile);
00615   CloseHandle(hFile);
00616 
00617   switch(BinType)
00618   {
00619     case BINARY_UNKNOWN:
00620     {
00621       WCHAR *dot;
00622 
00623       /*
00624        * guess from filename
00625        */
00626       if(!(dot = wcsrchr(lpApplicationName, L'.')))
00627       {
00628         return FALSE;
00629       }
00630       if(!lstrcmpiW(dot, L".COM"))
00631       {
00632         *lpBinaryType = SCS_DOS_BINARY;
00633         return TRUE;
00634       }
00635       if(!lstrcmpiW(dot, L".PIF"))
00636       {
00637         *lpBinaryType = SCS_PIF_BINARY;
00638         return TRUE;
00639       }
00640       return FALSE;
00641     }
00642     case BINARY_PE_EXE32:
00643     case BINARY_PE_DLL32:
00644     {
00645       *lpBinaryType = SCS_32BIT_BINARY;
00646       return TRUE;
00647     }
00648     case BINARY_PE_EXE64:
00649     case BINARY_PE_DLL64:
00650     {
00651       *lpBinaryType = SCS_64BIT_BINARY;
00652       return TRUE;
00653     }
00654     case BINARY_WIN16:
00655     {
00656       *lpBinaryType = SCS_WOW_BINARY;
00657       return TRUE;
00658     }
00659     case BINARY_OS216:
00660     {
00661       *lpBinaryType = SCS_OS216_BINARY;
00662       return TRUE;
00663     }
00664     case BINARY_DOS:
00665     {
00666       *lpBinaryType = SCS_DOS_BINARY;
00667       return TRUE;
00668     }
00669     case BINARY_UNIX_EXE:
00670     case BINARY_UNIX_LIB:
00671     {
00672       return FALSE;
00673     }
00674   }
00675 
00676   DPRINT1("Invalid binary type returned!\n", BinType);
00677   return FALSE;
00678 }
00679 
00680 /*
00681  * @implemented
00682  */
00683 BOOL
00684 WINAPI
00685 GetBinaryTypeA(IN LPCSTR lpApplicationName,
00686                OUT LPDWORD lpBinaryType)
00687 {
00688     ANSI_STRING ApplicationNameString;
00689     UNICODE_STRING ApplicationNameW;
00690     BOOL StringAllocated = FALSE, Result;
00691     NTSTATUS Status;
00692 
00693     RtlInitAnsiString(&ApplicationNameString, lpApplicationName);
00694 
00695     if (ApplicationNameString.Length * sizeof(WCHAR) >= NtCurrentTeb()->StaticUnicodeString.MaximumLength)
00696     {
00697         StringAllocated = TRUE;
00698         Status = RtlAnsiStringToUnicodeString(&ApplicationNameW, &ApplicationNameString, TRUE);
00699     }
00700     else
00701     {
00702         Status = RtlAnsiStringToUnicodeString(&(NtCurrentTeb()->StaticUnicodeString), &ApplicationNameString, FALSE);
00703     }
00704 
00705     if (!NT_SUCCESS(Status))
00706     {
00707         BaseSetLastNTError(Status);
00708         return FALSE;
00709     }
00710 
00711     if (StringAllocated)
00712     {
00713         Result = GetBinaryTypeW(ApplicationNameW.Buffer, lpBinaryType);
00714         RtlFreeUnicodeString(&ApplicationNameW);
00715     }
00716     else
00717     {
00718         Result = GetBinaryTypeW(NtCurrentTeb()->StaticUnicodeString.Buffer, lpBinaryType);
00719     }
00720 
00721     return Result;
00722 }
00723 
00724 /*
00725  * @unimplemented
00726  */
00727 BOOL
00728 WINAPI
00729 CmdBatNotification (
00730     DWORD   Unknown
00731     )
00732 {
00733     STUB;
00734     return FALSE;
00735 }
00736 
00737 /*
00738  * @unimplemented
00739  */
00740 DWORD
00741 WINAPI
00742 ExitVDM (
00743     DWORD   Unknown0,
00744     DWORD   Unknown1
00745     )
00746 {
00747     STUB;
00748     return 0;
00749 }
00750 
00751 
00752 /*
00753  * @unimplemented
00754  */
00755 DWORD
00756 WINAPI
00757 GetNextVDMCommand (
00758     DWORD   Unknown0
00759     )
00760 {
00761     STUB;
00762     return 0;
00763 }
00764 
00765 
00766 /*
00767  * @unimplemented
00768  */
00769 DWORD
00770 WINAPI
00771 GetVDMCurrentDirectories (
00772     DWORD   Unknown0,
00773     DWORD   Unknown1
00774     )
00775 {
00776     STUB;
00777     return 0;
00778 }
00779 
00780 
00781 /*
00782  * @unimplemented
00783  */
00784 BOOL
00785 WINAPI
00786 RegisterConsoleVDM (
00787     DWORD   Unknown0,
00788     DWORD   Unknown1,
00789     DWORD   Unknown2,
00790     DWORD   Unknown3,
00791     DWORD   Unknown4,
00792     DWORD   Unknown5,
00793     DWORD   Unknown6,
00794     DWORD   Unknown7,
00795     DWORD   Unknown8,
00796     DWORD   Unknown9,
00797     DWORD   Unknown10
00798     )
00799 {
00800     STUB;
00801     return FALSE;
00802 }
00803 
00804 
00805 /*
00806  * @unimplemented
00807  */
00808 BOOL
00809 WINAPI
00810 RegisterWowBaseHandlers (
00811     DWORD   Unknown0
00812     )
00813 {
00814     STUB;
00815     return FALSE;
00816 }
00817 
00818 
00819 /*
00820  * @unimplemented
00821  */
00822 BOOL
00823 WINAPI
00824 RegisterWowExec (
00825     DWORD   Unknown0
00826     )
00827 {
00828     STUB;
00829     return FALSE;
00830 }
00831 
00832 
00833 /*
00834  * @unimplemented
00835  */
00836 BOOL
00837 WINAPI
00838 SetVDMCurrentDirectories (
00839     DWORD   Unknown0,
00840     DWORD   Unknown1
00841     )
00842 {
00843     STUB;
00844     return FALSE;
00845 }
00846 
00847 /*
00848  * @unimplemented
00849  */
00850 DWORD
00851 WINAPI
00852 VDMConsoleOperation (
00853     DWORD   Unknown0,
00854     DWORD   Unknown1
00855     )
00856 {
00857     STUB;
00858     return 0;
00859 }
00860 
00861 
00862 /*
00863  * @unimplemented
00864  */
00865 DWORD
00866 WINAPI
00867 VDMOperationStarted (
00868     DWORD   Unknown0
00869     )
00870 {
00871     STUB;
00872     return 0;
00873 }

Generated on Fri May 25 2012 04:22:30 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.