2 * Unix SMB/CIFS implementation.
4 * SPOOLSS RPC Pipe server / winreg client routines
6 * Copyright (c) 2010 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "srv_spoolss_util.h"
24 #include "../librpc/gen_ndr/srv_winreg.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
28 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
29 #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
30 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
32 /* FLAGS, NAME, with, height, left, top, right, bottom */
33 static const struct spoolss_FormInfo1 builtin_forms1
[] = {
34 { SPOOLSS_FORM_BUILTIN
, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
35 { SPOOLSS_FORM_BUILTIN
, "Letter Small", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
36 { SPOOLSS_FORM_BUILTIN
, "Tabloid", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
37 { SPOOLSS_FORM_BUILTIN
, "Ledger", {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
38 { SPOOLSS_FORM_BUILTIN
, "Legal", {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
39 { SPOOLSS_FORM_BUILTIN
, "Statement", {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
40 { SPOOLSS_FORM_BUILTIN
, "Executive", {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
41 { SPOOLSS_FORM_BUILTIN
, "A3", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
42 { SPOOLSS_FORM_BUILTIN
, "A4", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
43 { SPOOLSS_FORM_BUILTIN
, "A4 Small", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
44 { SPOOLSS_FORM_BUILTIN
, "A5", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
45 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS)", {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
46 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS)", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
47 { SPOOLSS_FORM_BUILTIN
, "Folio", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
48 { SPOOLSS_FORM_BUILTIN
, "Quarto", {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
49 { SPOOLSS_FORM_BUILTIN
, "10x14", {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
50 { SPOOLSS_FORM_BUILTIN
, "11x17", {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
51 { SPOOLSS_FORM_BUILTIN
, "Note", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
52 { SPOOLSS_FORM_BUILTIN
, "Envelope #9", {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
53 { SPOOLSS_FORM_BUILTIN
, "Envelope #10", {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
54 { SPOOLSS_FORM_BUILTIN
, "Envelope #11", {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
55 { SPOOLSS_FORM_BUILTIN
, "Envelope #12", {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
56 { SPOOLSS_FORM_BUILTIN
, "Envelope #14", {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
57 { SPOOLSS_FORM_BUILTIN
, "C size sheet", {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
58 { SPOOLSS_FORM_BUILTIN
, "D size sheet", {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
59 { SPOOLSS_FORM_BUILTIN
, "E size sheet", {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
60 { SPOOLSS_FORM_BUILTIN
, "Envelope DL", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
61 { SPOOLSS_FORM_BUILTIN
, "Envelope C5", {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
62 { SPOOLSS_FORM_BUILTIN
, "Envelope C3", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
63 { SPOOLSS_FORM_BUILTIN
, "Envelope C4", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
64 { SPOOLSS_FORM_BUILTIN
, "Envelope C6", {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
65 { SPOOLSS_FORM_BUILTIN
, "Envelope C65", {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
66 { SPOOLSS_FORM_BUILTIN
, "Envelope B4", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
67 { SPOOLSS_FORM_BUILTIN
, "Envelope B5", {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
68 { SPOOLSS_FORM_BUILTIN
, "Envelope B6", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
69 { SPOOLSS_FORM_BUILTIN
, "Envelope", {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
70 { SPOOLSS_FORM_BUILTIN
, "Envelope Monarch", {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
71 { SPOOLSS_FORM_BUILTIN
, "6 3/4 Envelope", {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
72 { SPOOLSS_FORM_BUILTIN
, "US Std Fanfold", {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} },
73 { SPOOLSS_FORM_BUILTIN
, "German Std Fanfold", {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
74 { SPOOLSS_FORM_BUILTIN
, "German Legal Fanfold", {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
75 { SPOOLSS_FORM_BUILTIN
, "B4 (ISO)", {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
76 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard", {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
77 { SPOOLSS_FORM_BUILTIN
, "9x11", {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
78 { SPOOLSS_FORM_BUILTIN
, "10x11", {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
79 { SPOOLSS_FORM_BUILTIN
, "15x11", {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
80 { SPOOLSS_FORM_BUILTIN
, "Envelope Invite", {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
81 { SPOOLSS_FORM_BUILTIN
, "Reserved48", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
82 { SPOOLSS_FORM_BUILTIN
, "Reserved49", {0x1,0x1}, {0x0,0x0,0x1,0x1} },
83 { SPOOLSS_FORM_BUILTIN
, "Letter Extra", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
84 { SPOOLSS_FORM_BUILTIN
, "Legal Extra", {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
85 { SPOOLSS_FORM_BUILTIN
, "Tabloid Extra", {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
86 { SPOOLSS_FORM_BUILTIN
, "A4 Extra", {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
87 { SPOOLSS_FORM_BUILTIN
, "Letter Transverse", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
88 { SPOOLSS_FORM_BUILTIN
, "A4 Transverse", {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
89 { SPOOLSS_FORM_BUILTIN
, "Letter Extra Transverse", {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
90 { SPOOLSS_FORM_BUILTIN
, "Super A", {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
91 { SPOOLSS_FORM_BUILTIN
, "Super B", {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
92 { SPOOLSS_FORM_BUILTIN
, "Letter Plus", {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
93 { SPOOLSS_FORM_BUILTIN
, "A4 Plus", {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
94 { SPOOLSS_FORM_BUILTIN
, "A5 Transverse", {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
95 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Transverse", {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
96 { SPOOLSS_FORM_BUILTIN
, "A3 Extra", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
97 { SPOOLSS_FORM_BUILTIN
, "A5 Extra", {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
98 { SPOOLSS_FORM_BUILTIN
, "B5 (ISO) Extra", {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
99 { SPOOLSS_FORM_BUILTIN
, "A2", {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
100 { SPOOLSS_FORM_BUILTIN
, "A3 Transverse", {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
101 { SPOOLSS_FORM_BUILTIN
, "A3 Extra Transverse", {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
102 { SPOOLSS_FORM_BUILTIN
, "Japanese Double Postcard", {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
103 { SPOOLSS_FORM_BUILTIN
, "A6", {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
104 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #2", {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
105 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Kaku #3", {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
106 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #3", {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
107 { SPOOLSS_FORM_BUILTIN
, "Japanese Envelope Chou #4", {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
108 { SPOOLSS_FORM_BUILTIN
, "Letter Rotated", {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
109 { SPOOLSS_FORM_BUILTIN
, "A3 Rotated", {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
110 { SPOOLSS_FORM_BUILTIN
, "A4 Rotated", {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
111 { SPOOLSS_FORM_BUILTIN
, "A5 Rotated", {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
112 { SPOOLSS_FORM_BUILTIN
, "B4 (JIS) Rotated", {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
113 { SPOOLSS_FORM_BUILTIN
, "B5 (JIS) Rotated", {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
114 { SPOOLSS_FORM_BUILTIN
, "Japanese Postcard Rotated", {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
115 { SPOOLSS_FORM_BUILTIN
, "Double Japan Postcard Rotated", {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
116 { SPOOLSS_FORM_BUILTIN
, "A6 Rotated", {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
117 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
118 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
119 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
120 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
121 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS)", {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
122 { SPOOLSS_FORM_BUILTIN
, "B6 (JIS) Rotated", {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
123 { SPOOLSS_FORM_BUILTIN
, "12x11", {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
124 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4", {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
125 { SPOOLSS_FORM_BUILTIN
, "Japan Envelope You #4 Rotated", {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
126 { SPOOLSS_FORM_BUILTIN
, "PRC 16K", {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
127 { SPOOLSS_FORM_BUILTIN
, "PRC 32K", {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
128 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big)", {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
129 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1", {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
130 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2", {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
131 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3", {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
132 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4", {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
133 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5", {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
134 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6", {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
135 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7", {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
136 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8", {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
137 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9", {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
138 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10", {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
139 { SPOOLSS_FORM_BUILTIN
, "PRC 16K Rotated", {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
140 { SPOOLSS_FORM_BUILTIN
, "PRC 32K Rotated", {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
141 { SPOOLSS_FORM_BUILTIN
, "PRC 32K(Big) Rotated", {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
142 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #1 Rotated", {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
143 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #2 Rotated", {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
144 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #3 Rotated", {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
145 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #4 Rotated", {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
146 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #5 Rotated", {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
147 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #6 Rotated", {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
148 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #7 Rotated", {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
149 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #8 Rotated", {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
150 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #9 Rotated", {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
151 { SPOOLSS_FORM_BUILTIN
, "PRC Envelope #10 Rotated", {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }
154 /********************************************************************
155 static helper functions
156 ********************************************************************/
161 * @brief Connect to the interal winreg server and open the given printer key.
163 * The function will create the needed subkeys if they don't exist.
165 * @param[in] mem_ctx The memory context to use.
167 * @param[in] server_info The supplied server info.
169 * @param[out] winreg_pipe A pointer for the winreg rpc client pipe.
171 * @param[in] path The path to the key to open.
173 * @param[in] key The key to open.
175 * @param[in] create_key Set to true if the key should be created if it
178 * @param[in] access_mask The access mask to open the key.
180 * @param[out] hive_handle A policy handle for the opened hive.
182 * @param[out] key_handle A policy handle for the opened key.
184 * @return WERR_OK on success, the corresponding DOS error
185 * code if something gone wrong.
187 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
188 struct auth_serversupplied_info
*server_info
,
189 struct rpc_pipe_client
**winreg_pipe
,
193 uint32_t access_mask
,
194 struct policy_handle
*hive_handle
,
195 struct policy_handle
*key_handle
)
197 struct rpc_pipe_client
*pipe_handle
;
198 struct winreg_String wkey
, wkeyclass
;
201 WERROR result
= WERR_OK
;
203 /* create winreg connection */
204 status
= rpc_pipe_open_internal(mem_ctx
,
205 &ndr_table_winreg
.syntax_id
,
209 if (!NT_STATUS_IS_OK(status
)) {
210 DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
212 return ntstatus_to_werror(status
);
215 status
= rpccli_winreg_OpenHKLM(pipe_handle
,
221 if (!NT_STATUS_IS_OK(status
)) {
222 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
224 talloc_free(pipe_handle
);
225 if (!W_ERROR_IS_OK(result
)) {
228 return ntstatus_to_werror(status
);
232 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
234 keyname
= talloc_strdup(mem_ctx
, path
);
236 if (keyname
== NULL
) {
237 talloc_free(pipe_handle
);
245 enum winreg_CreateAction action
= REG_ACTION_NONE
;
247 ZERO_STRUCT(wkeyclass
);
250 status
= rpccli_winreg_CreateKey(pipe_handle
,
262 case REG_ACTION_NONE
:
263 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
265 case REG_CREATED_NEW_KEY
:
266 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
268 case REG_OPENED_EXISTING_KEY
:
269 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
273 status
= rpccli_winreg_OpenKey(pipe_handle
,
282 if (!NT_STATUS_IS_OK(status
)) {
283 talloc_free(pipe_handle
);
284 if (!W_ERROR_IS_OK(result
)) {
287 return ntstatus_to_werror(status
);
290 *winreg_pipe
= pipe_handle
;
296 * @brief Create the registry keyname for the given printer.
298 * @param[in] mem_ctx The memory context to use.
300 * @param[in] printer The name of the printer to get the registry key.
302 * @return The registry key or NULL on error.
304 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
305 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
311 * @brief Enumerate values of an opened key handle and retrieve the data.
313 * @param[in] mem_ctx The memory context to use.
315 * @param[in] pipe_handle The pipe handle for the rpc connection.
317 * @param[in] key_hnd The opened key handle.
319 * @param[out] pnum_values A pointer to store he number of values found.
321 * @param[out] pnum_values A pointer to store the number of values we found.
323 * @return WERR_OK on success, the corresponding DOS error
324 * code if something gone wrong.
326 static WERROR
winreg_printer_enumvalues(TALLOC_CTX
*mem_ctx
,
327 struct rpc_pipe_client
*pipe_handle
,
328 struct policy_handle
*key_hnd
,
329 uint32_t *pnum_values
,
330 struct spoolss_PrinterEnumValues
**penum_values
)
333 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
334 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
335 uint32_t secdescsize
;
337 NTTIME last_changed_time
;
338 struct winreg_String classname
;
340 struct spoolss_PrinterEnumValues
*enum_values
;
342 WERROR result
= WERR_OK
;
345 tmp_ctx
= talloc_new(mem_ctx
);
346 if (tmp_ctx
== NULL
) {
350 ZERO_STRUCT(classname
);
352 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
365 if (!NT_STATUS_IS_OK(status
)) {
366 DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
368 if (!W_ERROR_IS_OK(result
)) {
371 result
= ntstatus_to_werror(status
);
375 if (num_values
== 0) {
377 TALLOC_FREE(tmp_ctx
);
381 enum_values
= TALLOC_ARRAY(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
382 if (enum_values
== NULL
) {
387 for (i
= 0; i
< num_values
; i
++) {
388 struct spoolss_PrinterEnumValues val
;
389 struct winreg_ValNameBuf name_buf
;
390 enum winreg_Type type
= REG_NONE
;
391 uint8_t *data
= NULL
;
397 name_buf
.size
= max_valnamelen
+ 2;
400 data_size
= max_valbufsize
;
401 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
404 status
= rpccli_winreg_EnumValue(pipe_handle
,
414 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
416 status
= NT_STATUS_OK
;
420 if (!NT_STATUS_IS_OK(status
)) {
421 DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
423 if (!W_ERROR_IS_OK(result
)) {
426 result
= ntstatus_to_werror(status
);
430 if (name_buf
.name
== NULL
) {
431 result
= WERR_INVALID_PARAMETER
;
435 val
.value_name
= talloc_strdup(enum_values
, name_buf
.name
);
436 if (val
.value_name
== NULL
) {
440 val
.value_name_len
= strlen_m_term(val
.value_name
) * 2;
443 val
.data_length
= data_size
;
444 if (val
.data_length
) {
445 val
.data
= talloc(enum_values
, DATA_BLOB
);
446 if (val
.data
== NULL
) {
450 *val
.data
= data_blob_talloc(enum_values
, data
, data_size
);
453 enum_values
[i
] = val
;
456 *pnum_values
= num_values
;
458 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
464 TALLOC_FREE(tmp_ctx
);
471 * @brief Enumerate subkeys of an opened key handle and get the names.
473 * @param[in] mem_ctx The memory context to use.
475 * @param[in] pipe_handle The pipe handle for the rpc connection.
477 * @param[in] key_hnd The opened key handle.
479 * @param[in] pnum_subkeys A pointer to store the number of found subkeys.
481 * @param[in] psubkeys A pointer to an array to store the found names of
484 * @return WERR_OK on success, the corresponding DOS error
485 * code if something gone wrong.
487 static WERROR
winreg_printer_enumkeys(TALLOC_CTX
*mem_ctx
,
488 struct rpc_pipe_client
*pipe_handle
,
489 struct policy_handle
*key_hnd
,
490 uint32_t *pnum_subkeys
,
491 const char ***psubkeys
)
494 const char **subkeys
;
495 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
496 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
498 NTTIME last_changed_time
;
499 uint32_t secdescsize
;
500 struct winreg_String classname
;
501 WERROR result
= WERR_OK
;
504 tmp_ctx
= talloc_new(mem_ctx
);
505 if (tmp_ctx
== NULL
) {
509 ZERO_STRUCT(classname
);
511 status
= rpccli_winreg_QueryInfoKey(pipe_handle
,
524 if (!NT_STATUS_IS_OK(status
)) {
525 DEBUG(0, ("winreg_printer_enumkeys: Could not query info: %s\n",
527 if (!W_ERROR_IS_OK(result
)) {
530 result
= ntstatus_to_werror(status
);
534 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
535 if (subkeys
== NULL
) {
540 if (num_subkeys
== 0) {
541 subkeys
[0] = talloc_strdup(subkeys
, "");
542 if (subkeys
[0] == NULL
) {
548 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
551 TALLOC_FREE(tmp_ctx
);
555 for (i
= 0; i
< num_subkeys
; i
++) {
559 struct winreg_StringBuf class_buf
;
560 struct winreg_StringBuf name_buf
;
564 class_buf
.size
= max_classlen
+ 2;
565 class_buf
.length
= 0;
568 name_buf
.size
= max_subkeylen
+ 2;
571 ZERO_STRUCT(modtime
);
573 status
= rpccli_winreg_EnumKey(pipe_handle
,
581 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
583 status
= NT_STATUS_OK
;
587 if (!NT_STATUS_IS_OK(status
)) {
588 DEBUG(0, ("winreg_printer_enumkeys: Could not enumerate keys: %s\n",
590 if (!W_ERROR_IS_OK(result
)) {
593 result
= ntstatus_to_werror(status
);
597 if (name_buf
.name
== NULL
) {
598 result
= WERR_INVALID_PARAMETER
;
602 name
= talloc_strdup(subkeys
, name_buf
.name
);
611 *pnum_subkeys
= num_subkeys
;
613 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
617 TALLOC_FREE(tmp_ctx
);
624 * @brief A function to delete a key and its subkeys recurively.
626 * @param[in] mem_ctx The memory context to use.
628 * @param[in] pipe_handle The pipe handle for the rpc connection.
630 * @param[in] hive_handle A opened hive handle to the key.
632 * @param[in] access_mask The access mask to access the key.
634 * @param[in] key The key to delete
636 * @return WERR_OK on success, the corresponding DOS error
637 * code if something gone wrong.
639 static WERROR
winreg_printer_delete_subkeys(TALLOC_CTX
*mem_ctx
,
640 struct rpc_pipe_client
*pipe_handle
,
641 struct policy_handle
*hive_handle
,
642 uint32_t access_mask
,
645 const char **subkeys
= NULL
;
646 uint32_t num_subkeys
= 0;
647 struct policy_handle key_hnd
;
648 struct winreg_String wkey
;
649 WERROR result
= WERR_OK
;
653 ZERO_STRUCT(key_hnd
);
656 DEBUG(2, ("winreg_printer_delete_subkeys: delete key %s\n", key
));
658 status
= rpccli_winreg_OpenKey(pipe_handle
,
666 if (!NT_STATUS_IS_OK(status
)) {
667 DEBUG(0, ("winreg_printer_delete_subkeys: Could not open key %s: %s\n",
668 wkey
.name
, nt_errstr(status
)));
669 if (!W_ERROR_IS_OK(result
)) {
672 return ntstatus_to_werror(status
);
675 result
= winreg_printer_enumkeys(mem_ctx
,
680 if (!W_ERROR_IS_OK(result
)) {
684 for (i
= 0; i
< num_subkeys
; i
++) {
685 /* create key + subkey */
686 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
687 if (subkey
== NULL
) {
691 DEBUG(2, ("winreg_printer_delete_subkeys: delete subkey %s\n", subkey
));
692 result
= winreg_printer_delete_subkeys(mem_ctx
,
697 if (!W_ERROR_IS_OK(result
)) {
702 if (is_valid_policy_hnd(&key_hnd
)) {
703 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
708 status
= rpccli_winreg_DeleteKey(pipe_handle
,
715 if (is_valid_policy_hnd(&key_hnd
)) {
716 rpccli_winreg_CloseKey(pipe_handle
, mem_ctx
, &key_hnd
, NULL
);
722 /********************************************************************
723 Public winreg function for spoolss
724 ********************************************************************/
726 /* Set printer data over the winreg pipe. */
727 WERROR
winreg_set_printer_dataex(struct pipes_struct
*p
,
731 enum winreg_Type type
,
735 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
736 struct rpc_pipe_client
*winreg_pipe
= NULL
;
737 struct policy_handle hive_hnd
, key_hnd
;
738 struct winreg_String wvalue
;
740 WERROR result
= WERR_OK
;
744 tmp_ctx
= talloc_new(p
->mem_ctx
);
745 if (tmp_ctx
== NULL
) {
749 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
751 TALLOC_FREE(tmp_ctx
);
755 ZERO_STRUCT(hive_hnd
);
756 ZERO_STRUCT(key_hnd
);
758 DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
759 key
, value
, access_mask
, printer
));
760 result
= winreg_printer_openkey(tmp_ctx
,
769 if (!W_ERROR_IS_OK(result
)) {
770 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
771 key
, win_errstr(result
)));
776 status
= rpccli_winreg_SetValue(winreg_pipe
,
784 if (!NT_STATUS_IS_OK(status
)) {
785 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
786 value
, nt_errstr(status
)));
787 if (!W_ERROR_IS_OK(result
)) {
790 result
= ntstatus_to_werror(status
);
796 if (winreg_pipe
!= NULL
) {
797 if (is_valid_policy_hnd(&key_hnd
)) {
798 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
800 if (is_valid_policy_hnd(&hive_hnd
)) {
801 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
805 TALLOC_FREE(tmp_ctx
);
809 /* Get printer data over a winreg pipe. */
810 WERROR
winreg_get_printer_dataex(struct pipes_struct
*p
,
814 enum winreg_Type
*type
,
818 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
819 struct rpc_pipe_client
*winreg_pipe
= NULL
;
820 struct policy_handle hive_hnd
, key_hnd
;
821 struct winreg_String wvalue
;
822 enum winreg_Type type_in
;
825 uint32_t data_in_size
= 0;
826 uint32_t value_len
= 0;
827 WERROR result
= WERR_OK
;
831 tmp_ctx
= talloc_new(p
->mem_ctx
);
832 if (tmp_ctx
== NULL
) {
836 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
838 TALLOC_FREE(tmp_ctx
);
842 ZERO_STRUCT(hive_hnd
);
843 ZERO_STRUCT(key_hnd
);
845 result
= winreg_printer_openkey(tmp_ctx
,
854 if (!W_ERROR_IS_OK(result
)) {
855 DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
856 key
, win_errstr(result
)));
863 * call QueryValue once with data == NULL to get the
864 * needed memory size to be allocated, then allocate
865 * data buffer and call again.
867 status
= rpccli_winreg_QueryValue(winreg_pipe
,
876 if (!NT_STATUS_IS_OK(status
)) {
877 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
878 value
, nt_errstr(status
)));
879 if (!W_ERROR_IS_OK(result
)) {
882 result
= ntstatus_to_werror(status
);
886 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
887 if (data_in
== NULL
) {
893 status
= rpccli_winreg_QueryValue(winreg_pipe
,
902 if (!NT_STATUS_IS_OK(status
)) {
903 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
904 value
, nt_errstr(status
)));
905 if (!W_ERROR_IS_OK(result
)) {
906 result
= ntstatus_to_werror(status
);
912 *data_size
= data_in_size
;
914 *data
= talloc_move(p
->mem_ctx
, &data_in
);
919 if (winreg_pipe
!= NULL
) {
920 if (is_valid_policy_hnd(&key_hnd
)) {
921 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
923 if (is_valid_policy_hnd(&hive_hnd
)) {
924 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
928 TALLOC_FREE(tmp_ctx
);
932 /* Enumerate on the values of a given key and provide the data. */
933 WERROR
winreg_enum_printer_dataex(struct pipes_struct
*p
,
936 uint32_t *pnum_values
,
937 struct spoolss_PrinterEnumValues
**penum_values
)
939 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
940 struct rpc_pipe_client
*winreg_pipe
= NULL
;
941 struct policy_handle hive_hnd
, key_hnd
;
943 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
944 uint32_t num_values
= 0;
946 WERROR result
= WERR_OK
;
950 tmp_ctx
= talloc_new(p
->mem_ctx
);
951 if (tmp_ctx
== NULL
) {
955 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
957 TALLOC_FREE(tmp_ctx
);
961 result
= winreg_printer_openkey(tmp_ctx
,
970 if (!W_ERROR_IS_OK(result
)) {
971 DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
972 key
, win_errstr(result
)));
976 result
= winreg_printer_enumvalues(tmp_ctx
,
981 if (!W_ERROR_IS_OK(result
)) {
982 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
983 key
, win_errstr(result
)));
987 *pnum_values
= num_values
;
989 *penum_values
= talloc_move(p
->mem_ctx
, &enum_values
);
994 if (winreg_pipe
!= NULL
) {
995 if (is_valid_policy_hnd(&key_hnd
)) {
996 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
998 if (is_valid_policy_hnd(&hive_hnd
)) {
999 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1003 TALLOC_FREE(tmp_ctx
);
1007 /* Delete printer data over a winreg pipe. */
1008 WERROR
winreg_delete_printer_dataex(struct pipes_struct
*p
,
1009 const char *printer
,
1013 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1014 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1015 struct policy_handle hive_hnd
, key_hnd
;
1016 struct winreg_String wvalue
;
1018 WERROR result
= WERR_OK
;
1021 TALLOC_CTX
*tmp_ctx
;
1023 tmp_ctx
= talloc_new(p
->mem_ctx
);
1024 if (tmp_ctx
== NULL
) {
1028 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1030 TALLOC_FREE(tmp_ctx
);
1034 ZERO_STRUCT(hive_hnd
);
1035 ZERO_STRUCT(key_hnd
);
1037 result
= winreg_printer_openkey(tmp_ctx
,
1046 if (!W_ERROR_IS_OK(result
)) {
1047 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
1048 key
, win_errstr(result
)));
1052 wvalue
.name
= value
;
1053 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
1058 if (!NT_STATUS_IS_OK(status
)) {
1059 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
1060 value
, nt_errstr(status
)));
1061 if (!W_ERROR_IS_OK(result
)) {
1064 result
= ntstatus_to_werror(status
);
1070 if (winreg_pipe
!= NULL
) {
1071 if (is_valid_policy_hnd(&key_hnd
)) {
1072 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1074 if (is_valid_policy_hnd(&hive_hnd
)) {
1075 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1079 TALLOC_FREE(tmp_ctx
);
1083 /* Enumerate on the subkeys of a given key and provide the data. */
1084 WERROR
winreg_enum_printer_key(struct pipes_struct
*p
,
1085 const char *printer
,
1087 uint32_t *pnum_subkeys
,
1088 const char ***psubkeys
)
1090 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1091 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1092 struct policy_handle hive_hnd
, key_hnd
;
1094 const char **subkeys
= NULL
;
1095 uint32_t num_subkeys
= -1;
1097 WERROR result
= WERR_OK
;
1099 TALLOC_CTX
*tmp_ctx
;
1101 tmp_ctx
= talloc_new(p
->mem_ctx
);
1102 if (tmp_ctx
== NULL
) {
1106 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1108 TALLOC_FREE(tmp_ctx
);
1112 ZERO_STRUCT(hive_hnd
);
1113 ZERO_STRUCT(key_hnd
);
1115 result
= winreg_printer_openkey(tmp_ctx
,
1124 if (!W_ERROR_IS_OK(result
)) {
1125 DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
1126 key
, win_errstr(result
)));
1130 result
= winreg_printer_enumkeys(tmp_ctx
,
1135 if (!W_ERROR_IS_OK(result
)) {
1136 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
1137 key
, win_errstr(result
)));
1141 *pnum_subkeys
= num_subkeys
;
1143 *psubkeys
= talloc_move(p
->mem_ctx
, &subkeys
);
1148 if (winreg_pipe
!= NULL
) {
1149 if (is_valid_policy_hnd(&key_hnd
)) {
1150 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1152 if (is_valid_policy_hnd(&hive_hnd
)) {
1153 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1157 TALLOC_FREE(tmp_ctx
);
1161 /* Delete a key with subkeys of a given printer. */
1162 WERROR
winreg_delete_printer_key(struct pipes_struct
*p
,
1163 const char *printer
,
1166 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1167 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1168 struct policy_handle hive_hnd
, key_hnd
;
1172 TALLOC_CTX
*tmp_ctx
;
1174 tmp_ctx
= talloc_new(p
->mem_ctx
);
1175 if (tmp_ctx
== NULL
) {
1179 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1181 TALLOC_FREE(tmp_ctx
);
1185 result
= winreg_printer_openkey(tmp_ctx
,
1194 if (!W_ERROR_IS_OK(result
)) {
1195 /* key doesn't exist */
1196 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1201 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
1202 key
, win_errstr(result
)));
1206 if (is_valid_policy_hnd(&key_hnd
)) {
1207 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1210 keyname
= talloc_asprintf(tmp_ctx
,
1214 if (keyname
== NULL
) {
1215 result
= WERR_NOMEM
;
1219 result
= winreg_printer_delete_subkeys(tmp_ctx
,
1224 if (!W_ERROR_IS_OK(result
)) {
1225 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
1226 key
, win_errstr(result
)));
1231 if (winreg_pipe
!= NULL
) {
1232 if (is_valid_policy_hnd(&key_hnd
)) {
1233 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1235 if (is_valid_policy_hnd(&hive_hnd
)) {
1236 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1240 TALLOC_FREE(tmp_ctx
);
1245 * The special behaviour of the spoolss forms is documented at the website:
1247 * Managing Win32 Printserver Forms
1248 * http://unixwiz.net/techtips/winspooler-forms.html
1251 WERROR
winreg_printer_addform1(struct pipes_struct
*p
,
1252 struct spoolss_AddFormInfo1
*form
)
1254 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1255 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1256 struct policy_handle hive_hnd
, key_hnd
;
1257 struct winreg_String wvalue
;
1259 uint32_t num_info
= 0;
1260 union spoolss_FormInfo
*info
= NULL
;
1264 TALLOC_CTX
*tmp_ctx
;
1266 tmp_ctx
= talloc_new(p
->mem_ctx
);
1267 if (tmp_ctx
== NULL
) {
1271 ZERO_STRUCT(hive_hnd
);
1272 ZERO_STRUCT(key_hnd
);
1274 result
= winreg_printer_openkey(tmp_ctx
,
1277 TOP_LEVEL_CONTROL_FORMS_KEY
,
1283 if (!W_ERROR_IS_OK(result
)) {
1284 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
1285 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1289 result
= winreg_printer_enumforms1(p
, &num_info
, &info
);
1290 if (!W_ERROR_IS_OK(result
)) {
1291 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
1292 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1296 /* If form name already exists or is builtin return ALREADY_EXISTS */
1297 for (i
= 0; i
< num_info
; i
++) {
1298 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
1299 result
= WERR_FILE_EXISTS
;
1304 wvalue
.name
= form
->form_name
;
1306 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
1307 SIVAL(blob
.data
, 0, form
->size
.width
);
1308 SIVAL(blob
.data
, 4, form
->size
.height
);
1309 SIVAL(blob
.data
, 8, form
->area
.left
);
1310 SIVAL(blob
.data
, 12, form
->area
.top
);
1311 SIVAL(blob
.data
, 16, form
->area
.right
);
1312 SIVAL(blob
.data
, 20, form
->area
.bottom
);
1313 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
1314 SIVAL(blob
.data
, 28, form
->flags
);
1316 status
= rpccli_winreg_SetValue(winreg_pipe
,
1324 if (!NT_STATUS_IS_OK(status
)) {
1325 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
1326 wvalue
.name
, nt_errstr(status
)));
1327 if (!W_ERROR_IS_OK(result
)) {
1330 result
= ntstatus_to_werror(status
);
1336 if (winreg_pipe
!= NULL
) {
1337 if (is_valid_policy_hnd(&key_hnd
)) {
1338 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1340 if (is_valid_policy_hnd(&hive_hnd
)) {
1341 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1346 TALLOC_FREE(tmp_ctx
);
1350 WERROR
winreg_printer_enumforms1(struct pipes_struct
*p
,
1351 uint32_t *pnum_info
,
1352 union spoolss_FormInfo
**pinfo
)
1354 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1355 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1356 struct policy_handle hive_hnd
, key_hnd
;
1357 union spoolss_FormInfo
*info
;
1358 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
1359 uint32_t num_values
= 0;
1360 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
1363 TALLOC_CTX
*tmp_ctx
;
1365 tmp_ctx
= talloc_new(p
->mem_ctx
);
1366 if (tmp_ctx
== NULL
) {
1370 ZERO_STRUCT(hive_hnd
);
1371 ZERO_STRUCT(key_hnd
);
1373 result
= winreg_printer_openkey(tmp_ctx
,
1376 TOP_LEVEL_CONTROL_FORMS_KEY
,
1382 if (!W_ERROR_IS_OK(result
)) {
1383 /* key doesn't exist */
1384 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1389 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
1390 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1394 result
= winreg_printer_enumvalues(tmp_ctx
,
1399 if (!W_ERROR_IS_OK(result
)) {
1400 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
1401 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1405 info
= TALLOC_ARRAY(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
1407 result
= WERR_NOMEM
;
1411 /* Enumerate BUILTIN forms */
1412 for (i
= 0; i
< num_builtin
; i
++) {
1413 info
[i
].info1
= builtin_forms1
[i
];
1416 /* Enumerate registry forms */
1417 for (i
= 0; i
< num_values
; i
++) {
1418 union spoolss_FormInfo val
;
1420 if (enum_values
[i
].type
!= REG_BINARY
||
1421 enum_values
[i
].data_length
!= 32) {
1425 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
1426 if (val
.info1
.form_name
== NULL
) {
1427 result
= WERR_NOMEM
;
1431 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
1432 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
1433 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
1434 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
1435 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
1436 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
1437 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
1438 val
.info1
.flags
= IVAL(enum_values
[i
].data
->data
, 28);
1440 info
[i
+ num_builtin
] = val
;
1443 *pnum_info
= num_builtin
+ num_values
;
1445 *pinfo
= talloc_move(p
->mem_ctx
, &info
);
1449 if (winreg_pipe
!= NULL
) {
1450 if (is_valid_policy_hnd(&key_hnd
)) {
1451 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1453 if (is_valid_policy_hnd(&hive_hnd
)) {
1454 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1458 TALLOC_FREE(enum_values
);
1459 TALLOC_FREE(tmp_ctx
);
1463 WERROR
winreg_printer_deleteform1(struct pipes_struct
*p
,
1464 const char *form_name
)
1466 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1467 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1468 struct policy_handle hive_hnd
, key_hnd
;
1469 struct winreg_String wvalue
;
1470 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
1472 WERROR result
= WERR_OK
;
1474 TALLOC_CTX
*tmp_ctx
;
1476 for (i
= 0; i
< num_builtin
; i
++) {
1477 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
1478 return WERR_INVALID_PARAMETER
;
1482 tmp_ctx
= talloc_new(p
->mem_ctx
);
1483 if (tmp_ctx
== NULL
) {
1487 ZERO_STRUCT(hive_hnd
);
1488 ZERO_STRUCT(key_hnd
);
1490 result
= winreg_printer_openkey(tmp_ctx
,
1493 TOP_LEVEL_CONTROL_FORMS_KEY
,
1499 if (!W_ERROR_IS_OK(result
)) {
1500 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
1501 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1502 if (W_ERROR_EQUAL(result
, WERR_BADFILE
)) {
1503 result
= WERR_INVALID_FORM_NAME
;
1508 wvalue
.name
= form_name
;
1509 status
= rpccli_winreg_DeleteValue(winreg_pipe
,
1514 if (!NT_STATUS_IS_OK(status
)) {
1515 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
1516 wvalue
.name
, nt_errstr(status
)));
1517 if (!W_ERROR_IS_OK(result
)) {
1520 result
= ntstatus_to_werror(status
);
1526 if (winreg_pipe
!= NULL
) {
1527 if (is_valid_policy_hnd(&key_hnd
)) {
1528 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1530 if (is_valid_policy_hnd(&hive_hnd
)) {
1531 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1535 TALLOC_FREE(tmp_ctx
);
1539 WERROR
winreg_printer_setform1(struct pipes_struct
*p
,
1540 const char *form_name
,
1541 struct spoolss_AddFormInfo1
*form
)
1543 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1544 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1545 struct policy_handle hive_hnd
, key_hnd
;
1546 struct winreg_String wvalue
;
1548 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
1552 TALLOC_CTX
*tmp_ctx
;
1554 for (i
= 0; i
< num_builtin
; i
++) {
1555 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
1556 result
= WERR_INVALID_PARAM
;
1561 tmp_ctx
= talloc_new(p
->mem_ctx
);
1562 if (tmp_ctx
== NULL
) {
1566 ZERO_STRUCT(hive_hnd
);
1567 ZERO_STRUCT(key_hnd
);
1569 result
= winreg_printer_openkey(tmp_ctx
,
1572 TOP_LEVEL_CONTROL_FORMS_KEY
,
1578 if (!W_ERROR_IS_OK(result
)) {
1579 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
1580 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1584 /* If form_name != form->form_name then we renamed the form */
1585 if (strequal(form_name
, form
->form_name
)) {
1586 result
= winreg_printer_deleteform1(p
, form_name
);
1587 if (!W_ERROR_IS_OK(result
)) {
1588 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
1589 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1594 wvalue
.name
= form
->form_name
;
1596 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
1597 SIVAL(blob
.data
, 0, form
->size
.width
);
1598 SIVAL(blob
.data
, 4, form
->size
.height
);
1599 SIVAL(blob
.data
, 8, form
->area
.left
);
1600 SIVAL(blob
.data
, 12, form
->area
.top
);
1601 SIVAL(blob
.data
, 16, form
->area
.right
);
1602 SIVAL(blob
.data
, 20, form
->area
.bottom
);
1603 SIVAL(blob
.data
, 24, 42);
1604 SIVAL(blob
.data
, 28, form
->flags
);
1606 status
= rpccli_winreg_SetValue(winreg_pipe
,
1614 if (!NT_STATUS_IS_OK(status
)) {
1615 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
1616 wvalue
.name
, nt_errstr(status
)));
1617 if (!W_ERROR_IS_OK(result
)) {
1620 result
= ntstatus_to_werror(status
);
1626 if (winreg_pipe
!= NULL
) {
1627 if (is_valid_policy_hnd(&key_hnd
)) {
1628 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1630 if (is_valid_policy_hnd(&hive_hnd
)) {
1631 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1635 TALLOC_FREE(tmp_ctx
);
1639 WERROR
winreg_printer_getform1(struct pipes_struct
*p
,
1640 const char *form_name
,
1641 struct spoolss_FormInfo1
*r
)
1643 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1644 struct rpc_pipe_client
*winreg_pipe
= NULL
;
1645 struct policy_handle hive_hnd
, key_hnd
;
1646 struct winreg_String wvalue
;
1647 enum winreg_Type type_in
;
1649 uint32_t data_in_size
= 0;
1650 uint32_t value_len
= 0;
1651 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
1655 TALLOC_CTX
*tmp_ctx
;
1657 /* check builtin forms first */
1658 for (i
= 0; i
< num_builtin
; i
++) {
1659 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
1660 *r
= builtin_forms1
[i
];
1665 tmp_ctx
= talloc_new(p
->mem_ctx
);
1666 if (tmp_ctx
== NULL
) {
1670 ZERO_STRUCT(hive_hnd
);
1671 ZERO_STRUCT(key_hnd
);
1673 result
= winreg_printer_openkey(tmp_ctx
,
1676 TOP_LEVEL_CONTROL_FORMS_KEY
,
1682 if (!W_ERROR_IS_OK(result
)) {
1683 DEBUG(0, ("winreg_printer_getform1: Could not open key %s: %s\n",
1684 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
1688 wvalue
.name
= form_name
;
1691 * call QueryValue once with data == NULL to get the
1692 * needed memory size to be allocated, then allocate
1693 * data buffer and call again.
1695 status
= rpccli_winreg_QueryValue(winreg_pipe
,
1704 if (!NT_STATUS_IS_OK(status
)) {
1705 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
1706 wvalue
.name
, nt_errstr(status
)));
1707 if (!W_ERROR_IS_OK(result
)) {
1710 result
= ntstatus_to_werror(status
);
1714 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
1715 if (data_in
== NULL
) {
1716 result
= WERR_NOMEM
;
1721 status
= rpccli_winreg_QueryValue(winreg_pipe
,
1730 if (!NT_STATUS_IS_OK(status
)) {
1731 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
1732 wvalue
.name
, nt_errstr(status
)));
1733 if (!W_ERROR_IS_OK(result
)) {
1736 result
= ntstatus_to_werror(status
);
1740 r
->form_name
= talloc_strdup(p
->mem_ctx
, form_name
);
1741 if (r
->form_name
== NULL
) {
1742 result
= WERR_NOMEM
;
1746 r
->size
.width
= IVAL(data_in
, 0);
1747 r
->size
.height
= IVAL(data_in
, 4);
1748 r
->area
.left
= IVAL(data_in
, 8);
1749 r
->area
.top
= IVAL(data_in
, 12);
1750 r
->area
.right
= IVAL(data_in
, 16);
1751 r
->area
.bottom
= IVAL(data_in
, 20);
1752 /* skip index IVAL(data_in, 24)));*/
1753 r
->flags
= IVAL(data_in
, 28);
1757 if (winreg_pipe
!= NULL
) {
1758 if (is_valid_policy_hnd(&key_hnd
)) {
1759 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &key_hnd
, NULL
);
1761 if (is_valid_policy_hnd(&hive_hnd
)) {
1762 rpccli_winreg_CloseKey(winreg_pipe
, tmp_ctx
, &hive_hnd
, NULL
);
1766 TALLOC_FREE(tmp_ctx
);