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
Line 
1/* $Id: env.c,v 1.6 2001-07-08 03:13:16 bird Exp $
2 *
3 * Environment access functions
4 *
5 * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*******************************************************************************
12* Defined Constants And Macros *
13*******************************************************************************/
14#define INCL_DOSERRORS /* Error codes */
15#define INCL_OS2KRNL_VM /* OS2KRNL: Virtual Memory Management */
16#define INCL_OS2KRNL_PTDA /* OS2KRNL: (per)ProcessTaskDataArea */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <os2.h>
22
23#include "devSegDf.h" /* Win32k segment definitions. */
24#include "dev32.h"
25#include "dev32hlp.h"
26#include "log.h"
27#include "OS2Krnl.h"
28#include <string.h>
29#include "macros.h"
30#include "env.h"
31
32/*******************************************************************************
33* Internal Functions *
34*******************************************************************************/
35const char *GetEnv1(BOOL fExecChild);
36const char *GetEnv2(BOOL fExecChild);
37
38
39/**
40 * Scans the given environment data for a given environment variable and returns
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
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.)
53 */
54const char *ScanEnv(const char *paszEnv, const char *pszVar)
55{
56 int cchVar;
57 /*
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 /*
72 * Loop thru the environment data until an empty string is reached.
73 */
74 cchVar = strlen(pszVar);
75 while (*paszEnv != '\0')
76 {
77 /*
78 * Check if the variable name is it's matching the one we're searching for.
79 */
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;
89 }
90
91 /*
92 * Skip this variable. (Don't use pszEqual since it might be NULL)
93 */
94 paszEnv += strlen(paszEnv) + 1;
95 }
96
97 return NULL;
98}
99
100
101/**
102 * Get the linear pointer to the environment data for the current
103 * process or the process being started (EXECed).
104 *
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.
110 */
111const char *GetEnv(BOOL fExecChild)
112{
113 /* There are probably two ways of getting the environment data for the
114 * current process: 1) get it from the PTDA->ptda_environ
115 * 2) Local infosegment (LIS from GetDosVar devhlp)
116 * I am not sure which one of these which works best. What I know is that
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
122 * 2), testing will show which one of them are the better.
123 */
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}
133
134
135/**
136 * Method 1.
137 */
138const char *GetEnv1(BOOL fExecChild)
139{
140 PPTDA pPTDACur; /* Pointer to the current (system context) PTDA */
141 PPTDA pPTDA; /* PTDA in question. */
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.
151 * IF failed or no pPTDAExecChild THEN try get environment from pPTDA.
152 */
153 pPTDACur = ptdaGetCur();
154 if (pPTDACur != NULL)
155 {
156 pPTDA = ptdaGet_pPTDAExecChild(pPTDACur);
157 if (pPTDA != NULL && fExecChild)
158 {
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;
165 kprintf(("GetEnv: (1) VMObjHandleInfo failed with rc=%d for hob=0x%04x \n", rc, hobEnviron));
166 }
167 }
168
169 hobEnviron = ptdaGet_ptda_environ(pPTDACur);
170 if (hobEnviron != 0)
171 {
172 rc = VMObjHandleInfo(hobEnviron, SSToDS(&ulAddr), SSToDS(&ushPTDA));
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));
176 }
177 }
178 else
179 { /* Not called at task time? No current task! */
180 kprintf(("GetEnv: Failed to get current PTDA.\n"));
181 }
182
183 return NULL;
184}
185
186
187/**
188 * Method 2.
189 */
190const char *GetEnv2(BOOL fExecChild)
191{
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"));
204 NOREF(fExecChild);
205 return NULL;
206 }
207
208 if (pLIS->LIS_AX <= 3)
209 {
210 kprintf(("GetEnv: environment selector is %d, ie. NULL\n", pLIS->LIS_AX));
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 }
219
220 return (const char *)pv;
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! */
236 #endif
237}
Note: See TracBrowser for help on using the repository browser.