Create a branch for header work.

svn path=/branches/header-work/; revision=45691
This commit is contained in:
Timo Kreuzer 2010-02-26 22:57:55 +00:00
parent 14fe274b1c
commit 9ea495ba33
19538 changed files with 0 additions and 1063950 deletions

View 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;
}

View file

@ -0,0 +1,121 @@
/* $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;
}
// 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
View 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);
}

View 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);
}

View file

@ -0,0 +1,11 @@
#include <precomp.h>
#include <process.h>
/*
* @implemented
*/
int _getpid (void)
{
return (int)GetCurrentProcessId();
}

View 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);
}

View 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();
}

View 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 */

View file

@ -0,0 +1,4 @@
#define _UNICODE
#define UNICODE
#include "process.c"