Proper finalization in StartServiceW.
[wine] / dlls / gdi / env.c
1 /*
2  * Driver Environment functions
3  *
4  * Note: This has NOTHING to do with the task/process environment!
5  *
6  * Copyright 1997 Marcus Meissner
7  * Copyright 1998 Andreas Mohr
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "gdi.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
33
34 typedef struct {
35         ATOM atom;
36         HGLOBAL16 handle;
37 } ENVTABLE;
38
39 static ENVTABLE EnvTable[20];
40
41 static ENVTABLE *SearchEnvTable(ATOM atom)
42 {
43     INT16 i;
44
45     for (i = 19; i >= 0; i--) {
46       if (EnvTable[i].atom == atom)
47         return &EnvTable[i];
48     }
49     return NULL;
50 }
51
52 static ATOM GDI_GetNullPortAtom(void)
53 {
54     static ATOM NullPortAtom = 0;
55     if (!NullPortAtom)
56     {
57         char NullPort[256];
58
59         GetProfileStringA( "windows", "nullport", "none",
60                              NullPort, sizeof(NullPort) );
61         NullPortAtom = AddAtomA( NullPort );
62     }
63     return NullPortAtom;
64 }
65
66 static ATOM PortNameToAtom(LPCSTR lpPortName, BOOL16 add)
67 {
68     char buffer[256];
69
70     strncpy( buffer, lpPortName, sizeof(buffer) );
71     buffer[sizeof(buffer)-1] = 0;
72
73     if (buffer[0] && buffer[strlen(buffer)-1] == ':') buffer[strlen(buffer)-1] = 0;
74
75     if (add)
76         return AddAtomA(buffer);
77     else
78         return FindAtomA(buffer);
79 }
80
81
82 /***********************************************************************
83  *           GetEnvironment   (GDI.133)
84  */
85 INT16 WINAPI GetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nMaxSize)
86 {
87     ATOM atom;
88     LPCSTR p;
89     ENVTABLE *env;
90     WORD size;
91
92     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nMaxSize);
93
94     if (!(atom = PortNameToAtom(lpPortName, FALSE)))
95         return 0;
96     if (atom == GDI_GetNullPortAtom())
97         if (!(atom = FindAtomA((LPCSTR)lpdev)))
98             return 0;
99     if (!(env = SearchEnvTable(atom)))
100         return 0;
101     size = GlobalSize16(env->handle);
102     if (!lpdev) return 0;
103     if (size < nMaxSize) nMaxSize = size;
104     if (!(p = GlobalLock16(env->handle))) return 0;
105     memcpy(lpdev, p, nMaxSize);
106     GlobalUnlock16(env->handle);
107     return nMaxSize;
108 }
109
110
111 /***********************************************************************
112  *          SetEnvironment   (GDI.132)
113  */
114 INT16 WINAPI SetEnvironment16(LPCSTR lpPortName, LPDEVMODEA lpdev, UINT16 nCount)
115 {
116     ATOM atom;
117     BOOL16 nullport = FALSE;
118     LPSTR p;
119     ENVTABLE *env;
120     HGLOBAL16 handle;
121
122     TRACE("('%s', %p, %d)\n", lpPortName, lpdev, nCount);
123
124     if ((atom = PortNameToAtom(lpPortName, FALSE))) {
125         if (atom == GDI_GetNullPortAtom()) {
126             nullport = TRUE;
127             atom = FindAtomA((LPCSTR)lpdev);
128         }
129         env = SearchEnvTable(atom);
130         GlobalFree16(env->handle);
131         env->atom = 0;
132     }
133     if (nCount) { /* store DEVMODE struct */
134         if (nullport)
135             p = (LPSTR)lpdev;
136         else
137             p = (LPSTR)lpPortName;
138
139         if ((atom = PortNameToAtom(p, TRUE))
140          && (env = SearchEnvTable(0))
141          && (handle = GlobalAlloc16(GMEM_SHARE|GMEM_MOVEABLE, nCount))) {
142             if (!(p = GlobalLock16(handle))) {
143                 GlobalFree16(handle);
144                 return 0;
145             }
146             env->atom = atom;
147             env->handle = handle;
148             memcpy(p, lpdev, nCount);
149             GlobalUnlock16(handle);
150             return handle;
151         }
152         else return 0;
153     }
154     else return -1;
155 }