mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:23:01 +00:00
This really needs to go in a branch. It needs heavy testing and can't coincide with the current shell32 due to PSDK interface changes
svn path=/branches/shell32_new-bringup/; revision=51893
This commit is contained in:
parent
4596e5e59b
commit
4019caae75
23116 changed files with 0 additions and 1109022 deletions
32
lib/sdk/crt/process/_cwait.c
Normal file
32
lib/sdk/crt/process/_cwait.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/msvcrt/process/cwait.c
|
||||
* PURPOSE: Waits for a process to exit
|
||||
* PROGRAMER: Ariadne
|
||||
* UPDATE HISTORY:
|
||||
* 04/03/99: Created
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int _cwait(int* pnStatus, int hProc, int nAction)
|
||||
{
|
||||
DWORD ExitCode;
|
||||
|
||||
nAction = 0;
|
||||
if (WaitForSingleObject((void*)ULongToPtr(hProc), INFINITE) != WAIT_OBJECT_0) {
|
||||
__set_errno(ECHILD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!GetExitCodeProcess((void*)ULongToPtr(hProc), &ExitCode))
|
||||
return -1;
|
||||
if (pnStatus != NULL)
|
||||
*pnStatus = (int)ExitCode;
|
||||
CloseHandle((HANDLE)ULongToPtr(hProc));
|
||||
return hProc;
|
||||
}
|
124
lib/sdk/crt/process/_system.c
Normal file
124
lib/sdk/crt/process/_system.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* $Id$
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/msvcrt/process/system.c
|
||||
* PURPOSE: Excutes a shell command
|
||||
* PROGRAMER: Ariadne
|
||||
* UPDATE HISTORY:
|
||||
* 04/03/99: Created
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int system(const char *command)
|
||||
{
|
||||
char *szCmdLine = NULL;
|
||||
char *szComSpec = NULL;
|
||||
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
STARTUPINFOA StartupInfo;
|
||||
char *s;
|
||||
BOOL result;
|
||||
|
||||
int nStatus;
|
||||
|
||||
szComSpec = getenv("COMSPEC");
|
||||
|
||||
// system should return 0 if command is null and the shell is found
|
||||
|
||||
if (command == NULL) {
|
||||
if (szComSpec == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (szComSpec == NULL)
|
||||
return -1;
|
||||
|
||||
// should return 127 or 0 ( MS ) if the shell is not found
|
||||
// __set_errno(ENOENT);
|
||||
|
||||
if (szComSpec == NULL)
|
||||
{
|
||||
szComSpec = "cmd.exe";
|
||||
}
|
||||
|
||||
/* split the path from shell command */
|
||||
s = max(strrchr(szComSpec, '\\'), strrchr(szComSpec, '/'));
|
||||
if (s == NULL)
|
||||
s = szComSpec;
|
||||
else
|
||||
s++;
|
||||
|
||||
szCmdLine = malloc(strlen(s) + 4 + strlen(command) + 1);
|
||||
if (szCmdLine == NULL)
|
||||
{
|
||||
__set_errno(ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(szCmdLine, s);
|
||||
s = strrchr(szCmdLine, '.');
|
||||
if (s)
|
||||
*s = 0;
|
||||
strcat(szCmdLine, " /C ");
|
||||
strcat(szCmdLine, command);
|
||||
|
||||
//command file has invalid format ENOEXEC
|
||||
|
||||
memset (&StartupInfo, 0, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
StartupInfo.lpReserved= NULL;
|
||||
StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
|
||||
StartupInfo.wShowWindow = SW_SHOWDEFAULT;
|
||||
StartupInfo.lpReserved2 = NULL;
|
||||
StartupInfo.cbReserved2 = 0;
|
||||
|
||||
// According to ansi standards the new process should ignore SIGINT and SIGQUIT
|
||||
// In order to disable ctr-c the process is created with CREATE_NEW_PROCESS_GROUP,
|
||||
// thus SetConsoleCtrlHandler(NULL,TRUE) is made on behalf of the new process.
|
||||
|
||||
|
||||
//SIGCHILD should be blocked aswell
|
||||
|
||||
result = CreateProcessA(szComSpec,
|
||||
szCmdLine,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
CREATE_NEW_PROCESS_GROUP,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
free(szCmdLine);
|
||||
|
||||
if (result == FALSE)
|
||||
{
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
|
||||
// system should wait untill the calling process is finished
|
||||
_cwait(&nStatus,(intptr_t)ProcessInformation.hProcess,0);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
|
||||
return nStatus;
|
||||
}
|
||||
|
||||
int CDECL _wsystem(const wchar_t* cmd)
|
||||
{
|
||||
FIXME("_wsystem stub\n");
|
||||
return -1;
|
||||
}
|
39
lib/sdk/crt/process/dll.c
Normal file
39
lib/sdk/crt/process/dll.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/msvcrt/process/dll.c
|
||||
* PURPOSE: Dll support routines
|
||||
* PROGRAMER: Ariadne
|
||||
* UPDATE HISTORY:
|
||||
* 04/03/99: Created
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _loaddll(char* name)
|
||||
{
|
||||
return (intptr_t) LoadLibraryA(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int _unloaddll(intptr_t handle)
|
||||
{
|
||||
return FreeLibrary((HMODULE) handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
FARPROC _getdllprocaddr(intptr_t hModule, char* lpProcName, intptr_t iOrdinal)
|
||||
{
|
||||
if (lpProcName != NULL)
|
||||
return GetProcAddress((HMODULE) hModule, lpProcName);
|
||||
else
|
||||
return GetProcAddress((HMODULE) hModule, (LPSTR)iOrdinal);
|
||||
return (NULL);
|
||||
}
|
658
lib/sdk/crt/process/process.c
Normal file
658
lib/sdk/crt/process/process.c
Normal file
|
@ -0,0 +1,658 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT library
|
||||
* LICENSE: GPL (?) - See COPYING in the top level directory
|
||||
* FILE: lib/sdk/crt/process/process.c
|
||||
* PURPOSE: Process management functions
|
||||
* PROGRAMMERS: ???
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include <process.h>
|
||||
#include <tchar.h>
|
||||
#include <internal/wine/msvcrt.h>
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define sT "S"
|
||||
#define find_execT find_execW
|
||||
#define argvtosT argvtosW
|
||||
#define do_spawnT do_spawnW
|
||||
#define valisttosT valisttosW
|
||||
#define extT extW
|
||||
#else
|
||||
#define sT "s"
|
||||
#define find_execT find_execA
|
||||
#define argvtosT argvtosA
|
||||
#define do_spawnT do_spawnA
|
||||
#define valisttosT valisttosA
|
||||
#define extT extA
|
||||
#endif
|
||||
|
||||
#define MK_STR(s) #s
|
||||
|
||||
_TCHAR const* extT[] =
|
||||
{
|
||||
_T(""),
|
||||
_T(".bat"),
|
||||
_T(".cmd"),
|
||||
_T(".com"),
|
||||
_T(".exe")
|
||||
};
|
||||
|
||||
const _TCHAR* find_execT(const _TCHAR* path, _TCHAR* rpath)
|
||||
{
|
||||
_TCHAR *rp;
|
||||
const _TCHAR *rd;
|
||||
unsigned int i, found = 0;
|
||||
|
||||
TRACE(MK_STR(find_execT)"('%"sT"', %x)\n", path, rpath);
|
||||
|
||||
if (path == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (_tcslen(path) > FILENAME_MAX - 1)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
/* copy path in rpath */
|
||||
for (rd = path, rp = rpath; *rd; *rp++ = *rd++)
|
||||
;
|
||||
*rp = 0;
|
||||
/* try first with the name as is */
|
||||
for (i = 0; i < sizeof(extT) / sizeof(*extT); i++)
|
||||
{
|
||||
_tcscpy(rp, extT[i]);
|
||||
|
||||
TRACE("trying '%"sT"'\n", rpath);
|
||||
|
||||
if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
_TCHAR* env = _tgetenv(_T("PATH"));
|
||||
if (env)
|
||||
{
|
||||
_TCHAR* ep = env;
|
||||
while (*ep && !found)
|
||||
{
|
||||
if (*ep == ';')
|
||||
ep++;
|
||||
rp=rpath;
|
||||
for (; *ep && (*ep != ';'); *rp++ = *ep++)
|
||||
;
|
||||
if (rp > rpath)
|
||||
{
|
||||
rp--;
|
||||
if (*rp != '/' && *rp != '\\')
|
||||
{
|
||||
*++rp = '\\';
|
||||
}
|
||||
rp++;
|
||||
}
|
||||
for (rd=path; *rd; *rp++ = *rd++)
|
||||
;
|
||||
for (i = 0; i < sizeof(extT) / sizeof(*extT); i++)
|
||||
{
|
||||
_tcscpy(rp, extT[i]);
|
||||
|
||||
TRACE("trying '%"sT"'\n", rpath);
|
||||
|
||||
if (_taccess(rpath, F_OK) == 0 && access_dirT(rpath) != 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found ? rpath : path;
|
||||
}
|
||||
|
||||
static _TCHAR*
|
||||
argvtosT(const _TCHAR* const* argv, _TCHAR delim)
|
||||
{
|
||||
int i, len;
|
||||
_TCHAR *ptr, *str;
|
||||
|
||||
if (argv == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, len = 0; argv[i]; i++)
|
||||
{
|
||||
len += _tcslen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
str = ptr = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR));
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
for(i = 0; argv[i]; i++)
|
||||
{
|
||||
len = _tcslen(argv[i]);
|
||||
memcpy(ptr, argv[i], len * sizeof(_TCHAR));
|
||||
ptr += len;
|
||||
*ptr++ = delim;
|
||||
}
|
||||
*ptr = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static _TCHAR*
|
||||
valisttosT(const _TCHAR* arg0, va_list alist, _TCHAR delim)
|
||||
{
|
||||
va_list alist2 = alist;
|
||||
_TCHAR *ptr, *str;
|
||||
int len;
|
||||
|
||||
if (arg0 == NULL)
|
||||
return NULL;
|
||||
|
||||
ptr = (_TCHAR*)arg0;
|
||||
len = 0;
|
||||
do
|
||||
{
|
||||
len += _tcslen(ptr) + 1;
|
||||
ptr = va_arg(alist, _TCHAR*);
|
||||
}
|
||||
while(ptr != NULL);
|
||||
|
||||
str = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR));
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
ptr = str;
|
||||
do
|
||||
{
|
||||
len = _tcslen(arg0);
|
||||
memcpy(ptr, arg0, len * sizeof(_TCHAR));
|
||||
ptr += len;
|
||||
*ptr++ = delim;
|
||||
arg0 = va_arg(alist2, _TCHAR*);
|
||||
}
|
||||
while(arg0 != NULL);
|
||||
*ptr = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static intptr_t
|
||||
do_spawnT(int mode, const _TCHAR* cmdname, const _TCHAR* args, const _TCHAR* envp)
|
||||
{
|
||||
STARTUPINFO StartupInfo = {0};
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
// char* fmode;
|
||||
// HANDLE* hFile;
|
||||
// int i, last;
|
||||
BOOL bResult;
|
||||
DWORD dwExitCode;
|
||||
DWORD dwError;
|
||||
|
||||
TRACE(MK_STR(do_spawnT)"(%i,'%"sT"','%"sT"','%"sT"')",mode,cmdname,args,envp);
|
||||
|
||||
|
||||
if (mode != _P_NOWAIT && mode != _P_NOWAITO && mode != _P_WAIT && mode != _P_DETACH && mode != _P_OVERLAY)
|
||||
{
|
||||
__set_errno ( EINVAL );
|
||||
return( -1);
|
||||
}
|
||||
|
||||
if (0 != _taccess(cmdname, F_OK))
|
||||
{
|
||||
__set_errno ( ENOENT );
|
||||
return(-1);
|
||||
}
|
||||
if (0 == access_dirT(cmdname))
|
||||
{
|
||||
__set_errno ( EISDIR );
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memset (&StartupInfo, 0, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(StartupInfo);
|
||||
|
||||
#if 0
|
||||
|
||||
for (last = i = 0; i < FDINFO_FD_MAX; i++)
|
||||
{
|
||||
if ((void*)-1 != _get_osfhandle(i))
|
||||
{
|
||||
last = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (last)
|
||||
{
|
||||
StartupInfo.cbReserved2 = sizeof(ULONG) + last * (sizeof(char) + sizeof(HANDLE));
|
||||
StartupInfo.lpReserved2 = malloc(StartupInfo.cbReserved2);
|
||||
if (StartupInfo.lpReserved2 == NULL)
|
||||
{
|
||||
__set_errno ( ENOMEM );
|
||||
return -1;
|
||||
}
|
||||
|
||||
*(DWORD*)StartupInfo.lpReserved2 = last;
|
||||
fmode = (char*)(StartupInfo.lpReserved2 + sizeof(ULONG));
|
||||
hFile = (HANDLE*)(StartupInfo.lpReserved2 + sizeof(ULONG) + last * sizeof(char));
|
||||
for (i = 0; i < last; i++)
|
||||
{
|
||||
int _mode = __fileno_getmode(i);
|
||||
HANDLE h = _get_osfhandle(i);
|
||||
/* FIXME: The test of console handles (((ULONG)Handle) & 0x10000003) == 0x3)
|
||||
* is possible wrong
|
||||
*/
|
||||
if ((((ULONG)h) & 0x10000003) == 0x3 || _mode & _O_NOINHERIT || (i < 3 && mode == _P_DETACH))
|
||||
{
|
||||
*hFile = INVALID_HANDLE_VALUE;
|
||||
*fmode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwFlags;
|
||||
BOOL bFlag;
|
||||
bFlag = GetHandleInformation(h, &dwFlags);
|
||||
if (bFlag && (dwFlags & HANDLE_FLAG_INHERIT))
|
||||
{
|
||||
*hFile = h;
|
||||
*fmode = (_O_ACCMODE & _mode) | (((_O_TEXT | _O_BINARY) & _mode) >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
*hFile = INVALID_HANDLE_VALUE;
|
||||
*fmode = 0;
|
||||
}
|
||||
}
|
||||
fmode++;
|
||||
hFile++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
create_io_inherit_block(&StartupInfo.cbReserved2, &StartupInfo.lpReserved2);
|
||||
|
||||
bResult = CreateProcess((_TCHAR *)cmdname,
|
||||
(_TCHAR *)args,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
mode == _P_DETACH ? DETACHED_PROCESS : 0,
|
||||
(LPVOID)envp,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation);
|
||||
|
||||
if (StartupInfo.lpReserved2)
|
||||
{
|
||||
free(StartupInfo.lpReserved2);
|
||||
}
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
dwError = GetLastError();
|
||||
ERR("%x\n", dwError);
|
||||
_dosmaperr(dwError);
|
||||
return(-1);
|
||||
}
|
||||
CloseHandle(ProcessInformation.hThread);
|
||||
switch(mode)
|
||||
{
|
||||
case _P_NOWAIT:
|
||||
case _P_NOWAITO:
|
||||
return((intptr_t)ProcessInformation.hProcess);
|
||||
case _P_OVERLAY:
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
_exit(0);
|
||||
case _P_WAIT:
|
||||
WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
|
||||
GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
return( (int)dwExitCode); //CORRECT?
|
||||
case _P_DETACH:
|
||||
CloseHandle(ProcessInformation.hProcess);
|
||||
return( 0);
|
||||
}
|
||||
return( (intptr_t)ProcessInformation.hProcess);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnl(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ...)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_tspawnl)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, cmdname, args, NULL);
|
||||
free(args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnv(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv)
|
||||
{
|
||||
_TCHAR* args;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_tspawnv)"('%"sT"')\n", cmdname);
|
||||
|
||||
args = argvtosT(argv, ' ');
|
||||
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, cmdname, args, NULL);
|
||||
free(args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnle(int mode, const _TCHAR *cmdname, const _TCHAR* arg0, ... /*, NULL, const char* const* envp*/)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
_TCHAR* envs;
|
||||
_TCHAR const * const* ptr;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_tspawnle)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
do
|
||||
{
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
}
|
||||
while (ptr != NULL);
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
envs = argvtosT(ptr, 0);
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, cmdname, args, envs);
|
||||
free(args);
|
||||
}
|
||||
if (envs)
|
||||
{
|
||||
free(envs);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnve(int mode, const _TCHAR *cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp)
|
||||
{
|
||||
_TCHAR *args;
|
||||
_TCHAR *envs;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_tspawnve)"('%"sT"')\n", cmdname);
|
||||
|
||||
args = argvtosT(argv, ' ');
|
||||
envs = argvtosT(envp, 0);
|
||||
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, cmdname, args, envs);
|
||||
free(args);
|
||||
}
|
||||
if (envs)
|
||||
{
|
||||
free(envs);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnvp(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv)
|
||||
{
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_tspawnvp)"('%"sT"')\n", cmdname);
|
||||
|
||||
return _tspawnv(mode, find_execT(cmdname, pathname), argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnlp(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL*/)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
int ret = -1;
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_tspawnlp)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, find_execT(cmdname, pathname), args, NULL);
|
||||
free(args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnlpe(int mode, const _TCHAR* cmdname, const _TCHAR* arg0, .../*, NULL, const char* const* envp*/)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
_TCHAR* envs;
|
||||
_TCHAR const* const * ptr;
|
||||
int ret = -1;
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_tspawnlpe)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
do
|
||||
{
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
}
|
||||
while (ptr != NULL);
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
envs = argvtosT(ptr, 0);
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(mode, find_execT(cmdname, pathname), args, envs);
|
||||
free(args);
|
||||
}
|
||||
if (envs)
|
||||
{
|
||||
free(envs);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _tspawnvpe(int mode, const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp)
|
||||
{
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_tspawnvpe)"('%"sT"')\n", cmdname);
|
||||
|
||||
return _tspawnve(mode, find_execT(cmdname, pathname), argv, envp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecl(const _TCHAR* cmdname, const _TCHAR* arg0, ...)
|
||||
{
|
||||
_TCHAR* args;
|
||||
va_list argp;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_texecl)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(_P_OVERLAY, cmdname, args, NULL);
|
||||
free(args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecv(const _TCHAR* cmdname, const _TCHAR* const* argv)
|
||||
{
|
||||
TRACE(MK_STR(_texecv)"('%"sT"')\n", cmdname);
|
||||
return _tspawnv(_P_OVERLAY, cmdname, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecle(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* const* envp */)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
_TCHAR* envs;
|
||||
_TCHAR const* const* ptr;
|
||||
int ret = -1;
|
||||
|
||||
TRACE(MK_STR(_texecle)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
do
|
||||
{
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
}
|
||||
while (ptr != NULL);
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
envs = argvtosT(ptr, 0);
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(_P_OVERLAY, cmdname, args, envs);
|
||||
free(args);
|
||||
}
|
||||
if (envs)
|
||||
{
|
||||
free(envs);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecve(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp)
|
||||
{
|
||||
TRACE(MK_STR(_texecve)"('%"sT"')\n", cmdname);
|
||||
return _tspawnve(_P_OVERLAY, cmdname, argv, envp);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texeclp(const _TCHAR* cmdname, const _TCHAR* arg0, ...)
|
||||
{
|
||||
_TCHAR* args;
|
||||
va_list argp;
|
||||
int ret = -1;
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_texeclp)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(_P_OVERLAY, find_execT(cmdname, pathname), args, NULL);
|
||||
free(args);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecvp(const _TCHAR* cmdname, const _TCHAR* const* argv)
|
||||
{
|
||||
TRACE(MK_STR(_texecvp)"('%"sT"')\n", cmdname);
|
||||
return _tspawnvp(_P_OVERLAY, cmdname, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texeclpe(const _TCHAR* cmdname, const _TCHAR* arg0, ... /*, NULL, char* const* envp */)
|
||||
{
|
||||
va_list argp;
|
||||
_TCHAR* args;
|
||||
_TCHAR* envs;
|
||||
_TCHAR const* const* ptr;
|
||||
int ret = -1;
|
||||
_TCHAR pathname[FILENAME_MAX];
|
||||
|
||||
TRACE(MK_STR(_texeclpe)"('%"sT"')\n", cmdname);
|
||||
|
||||
va_start(argp, arg0);
|
||||
args = valisttosT(arg0, argp, ' ');
|
||||
do
|
||||
{
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
}
|
||||
while (ptr != NULL);
|
||||
ptr = (_TCHAR const* const*)va_arg(argp, _TCHAR*);
|
||||
envs = argvtosT(ptr, 0);
|
||||
if (args)
|
||||
{
|
||||
ret = do_spawnT(_P_OVERLAY, find_execT(cmdname, pathname), args, envs);
|
||||
free(args);
|
||||
}
|
||||
if (envs)
|
||||
{
|
||||
free(envs);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
intptr_t _texecvpe(const _TCHAR* cmdname, const _TCHAR* const* argv, const _TCHAR* const* envp)
|
||||
{
|
||||
TRACE(MK_STR(_texecvpe)"('%"sT"')\n", cmdname);
|
||||
return _tspawnvpe(_P_OVERLAY, cmdname, argv, envp);
|
||||
}
|
||||
|
||||
|
11
lib/sdk/crt/process/procid.c
Normal file
11
lib/sdk/crt/process/procid.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <precomp.h>
|
||||
#include <process.h>
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
int _getpid (void)
|
||||
{
|
||||
return (int)GetCurrentProcessId();
|
||||
}
|
||||
|
115
lib/sdk/crt/process/thread.c
Normal file
115
lib/sdk/crt/process/thread.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* msvcrt.dll thread functions
|
||||
*
|
||||
* Copyright 2000 Jon Griffiths
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <precomp.h>
|
||||
#include <internal/wine/msvcrt.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <process.h>
|
||||
|
||||
void _amsg_exit (int errnum);
|
||||
/* Index to TLS */
|
||||
DWORD MSVCRT_tls_index;
|
||||
|
||||
typedef void (*_beginthread_start_routine_t)(void *);
|
||||
typedef unsigned int (__stdcall *_beginthreadex_start_routine_t)(void *);
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
typedef struct {
|
||||
_beginthread_start_routine_t start_address;
|
||||
void *arglist;
|
||||
} _beginthread_trampoline_t;
|
||||
|
||||
/*********************************************************************
|
||||
* msvcrt_get_thread_data
|
||||
*
|
||||
* Return the thread local storage structure.
|
||||
*/
|
||||
MSVCRT_thread_data *msvcrt_get_thread_data(void)
|
||||
{
|
||||
MSVCRT_thread_data *ptr;
|
||||
DWORD err = GetLastError(); /* need to preserve last error */
|
||||
|
||||
if (!(ptr = TlsGetValue( MSVCRT_tls_index )))
|
||||
{
|
||||
if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
|
||||
_amsg_exit( _RT_THREAD );
|
||||
if (!TlsSetValue( MSVCRT_tls_index, ptr )) _amsg_exit( _RT_THREAD );
|
||||
ptr->random_seed = 1;
|
||||
}
|
||||
SetLastError( err );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* _beginthread_trampoline
|
||||
*/
|
||||
static DWORD CALLBACK _beginthread_trampoline(LPVOID arg)
|
||||
{
|
||||
_beginthread_trampoline_t local_trampoline;
|
||||
|
||||
/* Maybe it's just being paranoid, but freeing arg right
|
||||
* away seems safer.
|
||||
*/
|
||||
memcpy(&local_trampoline,arg,sizeof(local_trampoline));
|
||||
free(arg);
|
||||
|
||||
local_trampoline.start_address(local_trampoline.arglist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _beginthread (MSVCRT.@)
|
||||
*/
|
||||
uintptr_t _beginthread(
|
||||
_beginthread_start_routine_t start_address, /* [in] Start address of routine that begins execution of new thread */
|
||||
unsigned int stack_size, /* [in] Stack size for new thread or 0 */
|
||||
void *arglist) /* [in] Argument list to be passed to new thread or NULL */
|
||||
{
|
||||
_beginthread_trampoline_t* trampoline;
|
||||
|
||||
TRACE("(%p, %d, %p)\n", start_address, stack_size, arglist);
|
||||
|
||||
/* Allocate the trampoline here so that it is still valid when the thread
|
||||
* starts... typically after this function has returned.
|
||||
* _beginthread_trampoline is responsible for freeing the trampoline
|
||||
*/
|
||||
trampoline=malloc(sizeof(*trampoline));
|
||||
trampoline->start_address = start_address;
|
||||
trampoline->arglist = arglist;
|
||||
|
||||
/* FIXME */
|
||||
return (uintptr_t)CreateThread(NULL, stack_size, _beginthread_trampoline,
|
||||
trampoline, 0, NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _endthread (MSVCRT.@)
|
||||
*/
|
||||
void CDECL _endthread(void)
|
||||
{
|
||||
TRACE("(void)\n");
|
||||
|
||||
/* FIXME */
|
||||
ExitThread(0);
|
||||
}
|
||||
|
19
lib/sdk/crt/process/threadid.c
Normal file
19
lib/sdk/crt/process/threadid.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include <precomp.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
unsigned long __threadid (void)
|
||||
{
|
||||
return GetCurrentThreadId();
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
uintptr_t __threadhandle()
|
||||
{
|
||||
return (uintptr_t)GetCurrentThread();
|
||||
}
|
44
lib/sdk/crt/process/threadx.c
Normal file
44
lib/sdk/crt/process/threadx.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <precomp.h>
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
uintptr_t CDECL _beginthreadex(
|
||||
void* security,
|
||||
unsigned stack_size,
|
||||
unsigned (__stdcall *start_address)(void*),
|
||||
void* arglist,
|
||||
unsigned initflag,
|
||||
unsigned* thrdaddr)
|
||||
{
|
||||
HANDLE NewThread;
|
||||
|
||||
/*
|
||||
* Just call the API function. Any CRT specific processing is done in
|
||||
* DllMain DLL_THREAD_ATTACH
|
||||
*/
|
||||
NewThread = CreateThread ( security, stack_size,
|
||||
(LPTHREAD_START_ROUTINE)start_address,
|
||||
arglist, initflag, (PULONG)thrdaddr );
|
||||
if (NULL == NewThread)
|
||||
{
|
||||
_dosmaperr( GetLastError() );
|
||||
}
|
||||
|
||||
return (uintptr_t) NewThread;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
void CDECL _endthreadex(unsigned retval)
|
||||
{
|
||||
/*
|
||||
* Just call the API function. Any CRT specific processing is done in
|
||||
* DllMain DLL_THREAD_DETACH
|
||||
*/
|
||||
ExitThread(retval);
|
||||
}
|
||||
|
||||
/* EOF */
|
4
lib/sdk/crt/process/wprocess.c
Normal file
4
lib/sdk/crt/process/wprocess.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#define _UNICODE
|
||||
#define UNICODE
|
||||
|
||||
#include "process.c"
|
Loading…
Add table
Add a link
Reference in a new issue