Back to index

lightning-sunbird  0.9+nobinonly
Functions | Variables
ntmisc.c File Reference
#include "primpl.h"

Go to the source code of this file.

Functions

char * _PR_MD_GET_ENV (const char *name)
PRIntn _PR_MD_PUT_ENV (const char *name)
 PR_Now (void)
static int assembleCmdLine (char *const *argv, char **cmdLine)
static int assembleEnvBlock (char **envp, char **envBlock)
static int compare (const void *arg1, const void *arg2)
PRProcess_PR_CreateWindowsProcess (const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr)
PRStatus _PR_DetachWindowsProcess (PRProcess *process)
PRStatus _PR_WaitWindowsProcess (PRProcess *process, PRInt32 *exitCode)
PRStatus _PR_KillWindowsProcess (PRProcess *process)
PRStatus _MD_WindowsGetHostName (char *name, PRUint32 namelen)
PRStatus _MD_WindowsGetSysInfo (PRSysInfo cmd, char *name, PRUint32 namelen)
PRStatus _MD_WindowsGetReleaseName (char *name, PRUint32 namelen)
PRStatus _MD_CreateFileMap (PRFileMap *fmap, PRInt64 size)
PRInt32 _MD_GetMemMapAlignment (void)
void_MD_MemMap (PRFileMap *fmap, PROffset64 offset, PRUint32 len)
PRStatus _MD_MemUnmap (void *addr, PRUint32 len)
PRStatus _MD_CloseFileMap (PRFileMap *fmap)

Variables

PRLogModuleInfo_pr_shma_lm

Function Documentation

Definition at line 670 of file ntmisc.c.

{
    CloseHandle(fmap->md.hFileMap);
    PR_DELETE(fmap);
    return PR_SUCCESS;
}
PRStatus _MD_CreateFileMap ( PRFileMap fmap,
PRInt64  size 
)

Definition at line 582 of file ntmisc.c.

{
    DWORD dwHi, dwLo;
    DWORD flProtect;
    PRUint32    osfd;

    osfd = ( fmap->fd == (PRFileDesc*)-1 )?  -1 : fmap->fd->secret->md.osfd;

    dwLo = (DWORD) (size & 0xffffffff);
    dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff);

    if (fmap->prot == PR_PROT_READONLY) {
        flProtect = PAGE_READONLY;
        fmap->md.dwAccess = FILE_MAP_READ;
    } else if (fmap->prot == PR_PROT_READWRITE) {
        flProtect = PAGE_READWRITE;
        fmap->md.dwAccess = FILE_MAP_WRITE;
    } else {
        PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY);
        flProtect = PAGE_WRITECOPY;
        fmap->md.dwAccess = FILE_MAP_COPY;
    }

    fmap->md.hFileMap = CreateFileMapping(
        (HANDLE) osfd,
        NULL,
        flProtect,
        dwHi,
        dwLo,
        NULL);

    if (fmap->md.hFileMap == NULL) {
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
        return PR_FAILURE;
    }
    return PR_SUCCESS;
}

Definition at line 620 of file ntmisc.c.

{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return info.dwAllocationGranularity;
}
void* _MD_MemMap ( PRFileMap fmap,
PROffset64  offset,
PRUint32  len 
)

Definition at line 629 of file ntmisc.c.

{
    DWORD dwHi, dwLo;
    void *addr;

    dwLo = (DWORD) (offset & 0xffffffff);
    dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff);
    if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess,
            dwHi, dwLo, len)) == NULL) {
        {
            LPVOID lpMsgBuf; 
            
            FormatMessage( 
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                (LPTSTR) &lpMsgBuf,
                0,
                NULL 
            );
            PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf ));
        }
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
    }
    return addr;
}
PRStatus _MD_MemUnmap ( void addr,
PRUint32  len 
)

Definition at line 660 of file ntmisc.c.

{
    if (UnmapViewOfFile(addr)) {
        return PR_SUCCESS;
    } else {
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
        return PR_FAILURE;
    }
}
PRStatus _MD_WindowsGetHostName ( char *  name,
PRUint32  namelen 
)

Definition at line 490 of file ntmisc.c.

{
    PRIntn rv;
    PRInt32 syserror;

    rv = gethostname(name, (PRInt32) namelen);
    if (0 == rv) {
        return PR_SUCCESS;
    }
    syserror = WSAGetLastError();
    PR_ASSERT(WSANOTINITIALISED != syserror);
       _PR_MD_MAP_GETHOSTNAME_ERROR(syserror);
    return PR_FAILURE;
}

Here is the call graph for this function:

PRStatus _MD_WindowsGetReleaseName ( char *  name,
PRUint32  namelen 
)

Definition at line 549 of file ntmisc.c.

{
       OSVERSIONINFO osvi;

       ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
       osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

       if (! GetVersionEx (&osvi) ) {
              _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
       return PR_FAILURE;
       }

       switch (osvi.dwPlatformId) {
              case VER_PLATFORM_WIN32_NT:
              case VER_PLATFORM_WIN32_WINDOWS:
                     (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
                                                        osvi.dwMinorVersion);
                     break;
              default:
                     (void)PR_snprintf(name, namelen, "%d.%d",0,0);
                     break;
       }
       return PR_SUCCESS;
}

Here is the call graph for this function:

PRStatus _MD_WindowsGetSysInfo ( PRSysInfo  cmd,
char *  name,
PRUint32  namelen 
)

Definition at line 505 of file ntmisc.c.

{
       OSVERSIONINFO osvi;

       PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE));

       ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
       osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

       if (! GetVersionEx (&osvi) ) {
              _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
       return PR_FAILURE;
       }

       switch (osvi.dwPlatformId) {
              case VER_PLATFORM_WIN32_NT:
                     if (PR_SI_SYSNAME == cmd)
                            (void)PR_snprintf(name, namelen, "Windows_NT");
                     else if (PR_SI_RELEASE == cmd)
                            (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
                                                        osvi.dwMinorVersion);
                     break;
              case VER_PLATFORM_WIN32_WINDOWS:
                     if (PR_SI_SYSNAME == cmd) {
                            if ((osvi.dwMajorVersion > 4) || 
                                   ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0)))
                                   (void)PR_snprintf(name, namelen, "Windows_98");
                            else
                                   (void)PR_snprintf(name, namelen, "Windows_95");
                     } else if (PR_SI_RELEASE == cmd) {
                            (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, 
                                                        osvi.dwMinorVersion);
                     }
                     break;
              default:
                     if (PR_SI_SYSNAME == cmd)
                            (void)PR_snprintf(name, namelen, "Windows_Unknown");
                     else if (PR_SI_RELEASE == cmd)
                            (void)PR_snprintf(name, namelen, "%d.%d",0,0);
                     break;
       }
       return PR_SUCCESS;
}

Here is the call graph for this function:

PRProcess* _PR_CreateWindowsProcess ( const char *  path,
char *const argv,
char *const envp,
const PRProcessAttr attr 
)

Definition at line 296 of file ntmisc.c.

{
    STARTUPINFO startupInfo;
    PROCESS_INFORMATION procInfo;
    BOOL retVal;
    char *cmdLine = NULL;
    char *envBlock = NULL;
    char **newEnvp = NULL;
    const char *cwd = NULL; /* current working directory */
    PRProcess *proc = NULL;

    proc = PR_NEW(PRProcess);
    if (!proc) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }

    if (assembleCmdLine(argv, &cmdLine) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }

    /*
     * If attr->fdInheritBuffer is not NULL, we need to insert
     * it into the envp array, so envp cannot be NULL.
     */
    if ((envp == NULL) && attr && attr->fdInheritBuffer) {
        envp = environ;
    }

    if (envp != NULL) {
        int idx;
        int numEnv;
        int newEnvpSize;

        numEnv = 0;
        while (envp[numEnv]) {
            numEnv++;
        }
        newEnvpSize = numEnv + 1;  /* terminating null pointer */
        if (attr && attr->fdInheritBuffer) {
            newEnvpSize++;
        }
        newEnvp = (char **) PR_MALLOC(newEnvpSize * sizeof(char *));
        for (idx = 0; idx < numEnv; idx++) {
            newEnvp[idx] = envp[idx];
        }
        if (attr && attr->fdInheritBuffer) {
            newEnvp[idx++] = attr->fdInheritBuffer;
        }
        newEnvp[idx] = NULL;
        qsort((void *) newEnvp, (size_t) (newEnvpSize - 1),
                sizeof(char *), compare);
    }
    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }

    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);

    if (attr) {
        PRBool redirected = PR_FALSE;

        /*
         * XXX the default value for stdin, stdout, and stderr
         * should probably be the console input and output, not
         * those of the parent process.
         */
        startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        startupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
        startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
        if (attr->stdinFd) {
            startupInfo.hStdInput = (HANDLE) attr->stdinFd->secret->md.osfd;
            redirected = PR_TRUE;
        }
        if (attr->stdoutFd) {
            startupInfo.hStdOutput = (HANDLE) attr->stdoutFd->secret->md.osfd;
            redirected = PR_TRUE;
        }
        if (attr->stderrFd) {
            startupInfo.hStdError = (HANDLE) attr->stderrFd->secret->md.osfd;
            redirected = PR_TRUE;
        }
        if (redirected) {
            startupInfo.dwFlags |= STARTF_USESTDHANDLES;
        }
        cwd = attr->currentDirectory;
    }

    retVal = CreateProcess(NULL,
                           cmdLine,
                           NULL,  /* security attributes for the new
                                   * process */
                           NULL,  /* security attributes for the primary
                                   * thread in the new process */
                           TRUE,  /* inherit handles */
                           0,     /* creation flags */
                           envBlock,  /* an environment block, consisting
                                       * of a null-terminated block of
                                       * null-terminated strings.  Each
                                       * string is in the form:
                                       *     name=value
                                       * XXX: usually NULL */
                           cwd,  /* current drive and directory */
                           &startupInfo,
                           &procInfo
                          );
    if (retVal == FALSE) {
        /* XXX what error code? */
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
        goto errorExit;
    }

    CloseHandle(procInfo.hThread);
    proc->md.handle = procInfo.hProcess;
    proc->md.id = procInfo.dwProcessId;

    PR_DELETE(cmdLine);
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    return proc;

errorExit:
    if (cmdLine) {
        PR_DELETE(cmdLine);
    }
    if (newEnvp) {
        PR_DELETE(newEnvp);
    }
    if (envBlock) {
        PR_DELETE(envBlock);
    }
    if (proc) {
        PR_DELETE(proc);
    }
    return NULL;
}  /* _PR_CreateWindowsProcess */

Here is the call graph for this function:

Definition at line 444 of file ntmisc.c.

{
    CloseHandle(process->md.handle);
    PR_DELETE(process);
    return PR_SUCCESS;
}

Definition at line 476 of file ntmisc.c.

{
    /*
     * On Unix, if a process terminates normally, its exit code is
     * between 0 and 255.  So here on Windows, we use the exit code
     * 256 to indicate that the process is killed.
     */
    if (TerminateProcess(process->md.handle, 256)) {
       return PR_SUCCESS;
    }
    PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
    return PR_FAILURE;
}
char* _PR_MD_GET_ENV ( const char *  name)

Definition at line 45 of file ntmisc.c.

{
    return getenv(name);
}
PRIntn _PR_MD_PUT_ENV ( const char *  name)

Definition at line 55 of file ntmisc.c.

{
    return(putenv(name));
}
PRStatus _PR_WaitWindowsProcess ( PRProcess process,
PRInt32 exitCode 
)

Definition at line 455 of file ntmisc.c.

{
    DWORD dwRetVal;

    dwRetVal = WaitForSingleObject(process->md.handle, INFINITE);
    if (dwRetVal == WAIT_FAILED) {
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
        return PR_FAILURE;
    }
    PR_ASSERT(dwRetVal == WAIT_OBJECT_0);
    if (exitCode != NULL &&
            GetExitCodeProcess(process->md.handle, exitCode) == FALSE) {
        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
        return PR_FAILURE;
    }
    CloseHandle(process->md.handle);
    PR_DELETE(process);
    return PR_SUCCESS;
}
static int assembleCmdLine ( char *const argv,
char **  cmdLine 
) [static]

Definition at line 111 of file ntmisc.c.

{
    char *const *arg;
    char *p, *q;
    int cmdLineSize;
    int numBackslashes;
    int i;
    int argNeedQuotes;

    /*
     * Find out how large the command line buffer should be.
     */
    cmdLineSize = 0;
    for (arg = argv; *arg; arg++) {
        /*
         * \ and " need to be escaped by a \.  In the worst case,
         * every character is a \ or ", so the string of length
         * may double.  If we quote an argument, that needs two ".
         * Finally, we need a space between arguments, and
         * a null byte at the end of command line.
         */
        cmdLineSize += 2 * strlen(*arg)  /* \ and " need to be escaped */
                + 2                      /* we quote every argument */
                + 1;                     /* space in between, or final null */
    }
    p = *cmdLine = PR_MALLOC(cmdLineSize);
    if (p == NULL) {
        return -1;
    }

    for (arg = argv; *arg; arg++) {
        /* Add a space to separates the arguments */
        if (arg != argv) {
            *p++ = ' '; 
        }
        q = *arg;
        numBackslashes = 0;
        argNeedQuotes = 0;

        /* If the argument contains white space, it needs to be quoted. */
        if (strpbrk(*arg, " \f\n\r\t\v")) {
            argNeedQuotes = 1;
        }

        if (argNeedQuotes) {
            *p++ = '"';
        }
        while (*q) {
            if (*q == '\\') {
                numBackslashes++;
                q++;
            } else if (*q == '"') {
                if (numBackslashes) {
                    /*
                     * Double the backslashes since they are followed
                     * by a quote
                     */
                    for (i = 0; i < 2 * numBackslashes; i++) {
                        *p++ = '\\';
                    }
                    numBackslashes = 0;
                }
                /* To escape the quote */
                *p++ = '\\';
                *p++ = *q++;
            } else {
                if (numBackslashes) {
                    /*
                     * Backslashes are not followed by a quote, so
                     * don't need to double the backslashes.
                     */
                    for (i = 0; i < numBackslashes; i++) {
                        *p++ = '\\';
                    }
                    numBackslashes = 0;
                }
                *p++ = *q++;
            }
        }

        /* Now we are at the end of this argument */
        if (numBackslashes) {
            /*
             * Double the backslashes if we have a quote string
             * delimiter at the end.
             */
            if (argNeedQuotes) {
                numBackslashes *= 2;
            }
            for (i = 0; i < numBackslashes; i++) {
                *p++ = '\\';
            }
        }
        if (argNeedQuotes) {
            *p++ = '"';
        }
    } 

    *p = '\0';
    return 0;
}

Here is the caller graph for this function:

static int assembleEnvBlock ( char **  envp,
char **  envBlock 
) [static]

Definition at line 222 of file ntmisc.c.

{
    char *p;
    char *q;
    char **env;
    char *curEnv;
    char *cwdStart, *cwdEnd;
    int envBlockSize;

    if (envp == NULL) {
        *envBlock = NULL;
        return 0;
    }

    curEnv = GetEnvironmentStrings();

    cwdStart = curEnv;
    while (*cwdStart) {
        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
                && cwdStart[2] == ':' && cwdStart[3] == '=') {
            break;
        }
        cwdStart += strlen(cwdStart) + 1;
    }
    cwdEnd = cwdStart;
    if (*cwdEnd) {
        cwdEnd += strlen(cwdEnd) + 1;
        while (*cwdEnd) {
            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
                break;
            }
            cwdEnd += strlen(cwdEnd) + 1;
        }
    }
    envBlockSize = cwdEnd - cwdStart;

    for (env = envp; *env; env++) {
        envBlockSize += strlen(*env) + 1;
    }
    envBlockSize++;

    p = *envBlock = PR_MALLOC(envBlockSize);
    if (p == NULL) {
        FreeEnvironmentStrings(curEnv);
        return -1;
    }

    q = cwdStart;
    while (q < cwdEnd) {
        *p++ = *q++;
    }
    FreeEnvironmentStrings(curEnv);

    for (env = envp; *env; env++) {
        q = *env;
        while (*q) {
            *p++ = *q++;
        }
        *p++ = '\0';
    }
    *p = '\0';
    return 0;
}

Here is the caller graph for this function:

static int compare ( const void arg1,
const void arg2 
) [static]

Definition at line 291 of file ntmisc.c.

{
    return _stricmp(* (char**)arg1, * (char**)arg2);
}

Here is the caller graph for this function:

PR_Now ( void  )

Definition at line 86 of file ntmisc.c.

{
    PRTime prt;
    FILETIME ft;

    GetSystemTimeAsFileTime(&ft);
    _PR_FileTimeToPRTime(&ft, &prt);
    return prt;       
}

Here is the call graph for this function:


Variable Documentation

Definition at line 52 of file prinit.c.