source: trunk/src/win32k/misc/env.c

Last change on this file was 6232, checked in by bird, 24 years ago

Reorganized it a little bit. Finding that the environment isn't updated by Open32/Odin32... GetEnv2 is mostly working I think.

File size: 7.8 KB
RevLine 
[6232]1/* $Id: env.c,v 1.6 2001-07-08 03:13:16 bird Exp $
[3411]2 *
[3412]3 * Environment access functions
[3411]4 *
[4787]5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
[3411]6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
[3412]11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_DOSERRORS /* Error codes */
15#define INCL_OS2KRNL_VM /* OS2KRNL: Virtual Memory Management */
[5086]16#define INCL_OS2KRNL_PTDA /* OS2KRNL: (per)ProcessTaskDataArea */
[3411]17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <os2.h>
[3412]22
[4164]23#include "devSegDf.h" /* Win32k segment definitions. */
[3411]24#include "dev32.h"
25#include "dev32hlp.h"
[3412]26#include "log.h"
27#include "OS2Krnl.h"
[3411]28#include <string.h>
[4164]29#include "macros.h"
[3411]30#include "env.h"
31
[6232]32/*******************************************************************************
33* Internal Functions *
34*******************************************************************************/
35const char *GetEnv1(BOOL fExecChild);
36const char *GetEnv2(BOOL fExecChild);
[3411]37
[6232]38
[3411]39/**
[3412]40 * Scans the given environment data for a given environment variable and returns
[3411]41 * its value if found.
42 * @returns Pointer to environment variable value for the variable given in
43 * pszVar.
44 * If the variable wasn't found NULL is returned.
45 * @param paszEnv Pointer to the environment data to search.
46 * The environment data is a list of zero-strings terminated
[4164]47 * by an empty string. The strings consists of two parts which
48 * are separated by a euqal char ('='). The first part is the
49 * variable name. The second part is the value of the variable.
50 *
51 * IF this is NULL we'll simply return NULL.
52 * @param pszVar Name of the environment variable to find. (NULL not allowed.)
[3411]53 */
54const char *ScanEnv(const char *paszEnv, const char *pszVar)
55{
[4164]56 int cchVar;
[3411]57 /*
[4164]58 * Return if environment not found.
59 */
60 #ifdef DEBUG
61 if (pszVar < (const char *)0x10000 || *pszVar == '\0')
62 kprintf(("ScanEnv: Invalid parameter pszVar (%p)\n", pszVar));
63 #endif
64 if (paszEnv == NULL)
65 return NULL;
66 #ifdef DEBUG
67 if (paszEnv < (const char *)0x10000)
68 kprintf(("ScanEnv: Invalid parameter paszEnv (%p)\n", paszEnv));
69 #endif
70
71 /*
[3411]72 * Loop thru the environment data until an empty string is reached.
73 */
[4164]74 cchVar = strlen(pszVar);
[3411]75 while (*paszEnv != '\0')
76 {
77 /*
[4164]78 * Check if the variable name is it's matching the one we're searching for.
[3411]79 */
[4164]80 const char *pszEqual = strchr(paszEnv, '=');
81 if (pszEqual != NULL && (pszEqual - paszEnv) == cchVar
82 && memcmp(paszEnv, pszVar, cchVar) == 0
83 )
84 {
85 /*
86 * Variable was found. Return pointer to the value.
87 */
88 return pszEqual + 1;
[3411]89 }
90
91 /*
[4164]92 * Skip this variable. (Don't use pszEqual since it might be NULL)
[3411]93 */
94 paszEnv += strlen(paszEnv) + 1;
95 }
96
97 return NULL;
98}
99
100
101/**
[4164]102 * Get the linear pointer to the environment data for the current
103 * process or the process being started (EXECed).
[3412]104 *
[4164]105 * @param fExecChild TRUE: Get exec child environment.
106 * (Not supported by method 2)
107 * FALSE: Get current process environment.
108 * @returns Pointer to environment data.
109 * NULL on failure.
[3411]110 */
[4164]111const char *GetEnv(BOOL fExecChild)
[3411]112{
[4164]113 /* There are probably two ways of getting the environment data for the
[3411]114 * current process: 1) get it from the PTDA->ptda_environ
115 * 2) Local infosegment (LIS from GetDosVar devhlp)
[4164]116 * I am not sure which one of these which works best. What I know is that
[3411]117 * method 1) is used by the w_GetEnv API worker. This API is called at
118 * Ring-0 from some delete file operation. (Which uses it to get the
119 * DELETEDIR environment variable.) The w_GetEnv API worker is 16-bit
120 * I don't want to thunk around using that. There for I'll implement
121 * my own GetEnv. So, currently I'll write the code for both 1) and
[4164]122 * 2), testing will show which one of them are the better.
[3411]123 */
[6232]124 #if 1
125 return GetEnv1(fExecChild);
126 #else
127 const char *pszEnv = GetEnv2(fExecChild);
128 if (pszEnv == NULL)
129 pszEnv = GetEnv1(fExecChild);
130 return pszEnv;
131 #endif
132}
[3411]133
[6232]134
135/**
136 * Method 1.
137 */
138const char *GetEnv1(BOOL fExecChild)
139{
[3412]140 PPTDA pPTDACur; /* Pointer to the current (system context) PTDA */
141 PPTDA pPTDA; /* PTDA in question. */
[3411]142 USHORT hobEnviron; /* Object handle of the environ block */
143 APIRET rc; /* Return from VMObjHandleInfo. */
144 USHORT ushPTDA; /* Handle of the context PTDA. (VMObjH..) */
145 ULONG ulAddr = 0; /* Address of the environment data. */
146
147 /*
148 * Use PTDA (1):
149 * Get the current PTDA. (Fail if this call failes.)
150 * IF pPTDAExecChild isn't NULL THEN try get environment for that first.
[3412]151 * IF failed or no pPTDAExecChild THEN try get environment from pPTDA.
[3411]152 */
[3412]153 pPTDACur = ptdaGetCur();
[4164]154 if (pPTDACur != NULL)
[3411]155 {
[4164]156 pPTDA = ptdaGet_pPTDAExecChild(pPTDACur);
157 if (pPTDA != NULL && fExecChild)
[3411]158 {
[3412]159 hobEnviron = ptdaGet_ptda_environ(pPTDA);
160 if (hobEnviron != 0)
161 {
162 rc = VMObjHandleInfo(hobEnviron, SSToDS(&ulAddr), SSToDS(&ushPTDA));
163 if (rc == NO_ERROR)
164 return (const char *)ulAddr;
[4164]165 kprintf(("GetEnv: (1) VMObjHandleInfo failed with rc=%d for hob=0x%04x \n", rc, hobEnviron));
[3412]166 }
[3411]167 }
168
[3412]169 hobEnviron = ptdaGet_ptda_environ(pPTDACur);
[3411]170 if (hobEnviron != 0)
171 {
[3412]172 rc = VMObjHandleInfo(hobEnviron, SSToDS(&ulAddr), SSToDS(&ushPTDA));
[4164]173 if (rc == NO_ERROR)
174 return (const char *)ulAddr;
175 kprintf(("GetEnv: (2) VMObjHandleInfo failed with rc=%d for hob=0x%04x\n", rc, hobEnviron));
[3411]176 }
177 }
[3412]178 else
[4164]179 { /* Not called at task time? No current task! */
[3412]180 kprintf(("GetEnv: Failed to get current PTDA.\n"));
181 }
[3411]182
[4164]183 return NULL;
[6232]184}
[3412]185
[4164]186
[6232]187/**
188 * Method 2.
189 */
190const char *GetEnv2(BOOL fExecChild)
191{
[3411]192 struct InfoSegLDT * pLIS; /* Pointer to local infosegment. */
193 PVOID pv; /* Address to return. */
194
195
196 /*
197 * Use LocalInfoSegment (2)
198 * Get the LIS using Dh32_GetDosVar
199 */
200 pLIS = (struct InfoSegLDT*)D32Hlp_GetDOSVar(DHGETDOSV_LOCINFOSEG, 0);
201 if (pLIS == NULL)
202 {
203 kprintf(("GetEnv: Failed to get local info segment\n"));
[4164]204 NOREF(fExecChild);
[3412]205 return NULL;
[3411]206 }
207
208 if (pLIS->LIS_AX <= 3)
209 {
[3412]210 kprintf(("GetEnv: environment selector is %d, ie. NULL\n", pLIS->LIS_AX));
[3411]211 return NULL;
212 }
213
214 pv = D32Hlp_VirtToLin2(pLIS->LIS_AX, 0);
215 if (pv != NULL)
216 {
217 kprintf(("GetEnv: VirtToLin2 failed to thunk %04x:0000 to linar address\n", pLIS->LIS_AX));
218 }
[6232]219
[3411]220 return (const char *)pv;
[6232]221}
222
223
224
225
226/**
227 * Relase environment block retrieved by GetEnv.
228 * @param pszEnv Pointer to environment block.
229 */
230void RelaseEnv(const char *pszEnv)
231{
232 #if 0
233 pszEnv = pszEnv; /* nothing to do! */
234 #else
235 pszEnv = pszEnv; /* nothing to do yet! */
[3411]236 #endif
237}
Note: See TracBrowser for help on using the repository browser.