s3: Lift the smbd_messaging_context from winreg_printer_enumforms1
[amitay/samba.git] / source3 / rpc_server / srv_spoolss_util.c
index 0f6c30513cc8109fcc35dbd6f9eae746a8fabac6..aea9a5a7027fabe33cb0186d299c14733e558909 100644 (file)
  */
 
 #include "includes.h"
+#include "nt_printing.h"
 #include "srv_spoolss_util.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
 #include "../librpc/gen_ndr/srv_winreg.h"
 #include "../librpc/gen_ndr/cli_winreg.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "secrets.h"
 
 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
 #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
 
 #define EMPTY_STRING ""
-static const char *empty_string_array[1] = { NULL };
-#define EMPTY_STRING_ARRAY empty_string_array
+
+#define FILL_STRING(mem_ctx, in, out) \
+       do { \
+               if (in && strlen(in)) { \
+                       out = talloc_strdup(mem_ctx, in); \
+               } else { \
+                       out = talloc_strdup(mem_ctx, ""); \
+               } \
+               W_ERROR_HAVE_NO_MEMORY(out); \
+       } while (0);
 
 #define CHECK_ERROR(result) \
        if (W_ERROR_IS_OK(result)) continue; \
@@ -40,124 +52,126 @@ static const char *empty_string_array[1] = { NULL };
 
 /*        FLAGS,                NAME,                              with,   height,   left, top, right, bottom */
 static const struct spoolss_FormInfo1 builtin_forms1[] = {
-       { SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-       { SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
-       { SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
-       { SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
+       { SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
+       { SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+       { SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
+       { SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
+       { SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "A0",                             {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
+       { SPOOLSS_FORM_BUILTIN, "A1",                             {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
+       { SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
        { SPOOLSS_FORM_BUILTIN, "A3",                             {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-       { SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
        { SPOOLSS_FORM_BUILTIN, "A4 Small",                       {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
        { SPOOLSS_FORM_BUILTIN, "A5",                             {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
+       { SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
        { SPOOLSS_FORM_BUILTIN, "B4 (JIS)",                       {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
        { SPOOLSS_FORM_BUILTIN, "B5 (JIS)",                       {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-       { SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
-       { SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
-       { SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-       { SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
+       { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
+       { SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
+       { SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
+       { SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
+       { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
+       { SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #10",                   {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #11",                   {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #12",                   {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #14",                   {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
-       { SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
-       { SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
-       { SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C3",                    {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C4",                    {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C6",                    {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C65",                   {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
        { SPOOLSS_FORM_BUILTIN, "Envelope Monarch",               {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
-       { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
-       { SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
+       { SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
+       { SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
        { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold",           {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-       { SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
        { SPOOLSS_FORM_BUILTIN, "Japanese Postcard",              {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-       { SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
        { SPOOLSS_FORM_BUILTIN, "Legal Extra",                    {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
-       { SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
        { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse",        {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
-       { SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
-       { SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
        { SPOOLSS_FORM_BUILTIN, "Letter Plus",                    {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
-       { SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
        { SPOOLSS_FORM_BUILTIN, "Letter Rotated",                 {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
-       { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
-       { SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
-       { SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
-       { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
-       { SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
        { SPOOLSS_FORM_BUILTIN, "PRC 16K",                        {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
        { SPOOLSS_FORM_BUILTIN, "PRC 32K",                        {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
        { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)",                   {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1",                {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10",               {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated",        {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated",        {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated",        {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated",        {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated",        {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated",        {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated",        {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated",        {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
+       { SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+       { SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+       { SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
+       { SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
+       { SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
+       { SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
+       { SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+       { SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
 };
 
 /********************************************************************
@@ -198,72 +212,6 @@ static uint32_t winreg_printer_rev_changeid(void)
 #endif
 }
 
-static struct spoolss_DeviceMode *winreg_printer_create_default_devmode(TALLOC_CTX *mem_ctx,
-               const char *default_devicename)
-{
-       char adevice[MAXDEVICENAME];
-       struct spoolss_DeviceMode *devmode;
-
-       devmode = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-       if (devmode == NULL) {
-               return NULL;
-       }
-
-       slprintf(adevice, sizeof(adevice), "%s", default_devicename);
-       devmode->devicename = talloc_strdup(mem_ctx, adevice);
-       if (devmode->devicename == NULL) {
-               return NULL;
-       }
-
-       devmode->formname = "Letter";
-
-       devmode->specversion          = DMSPEC_NT4_AND_ABOVE;
-       devmode->driverversion        = 0x0400;
-       devmode->size                 = 0x00DC;
-       devmode->__driverextra_length = 0;
-       devmode->fields               = DEVMODE_FORMNAME |
-                                       DEVMODE_TTOPTION |
-                                       DEVMODE_PRINTQUALITY |
-                                       DEVMODE_DEFAULTSOURCE |
-                                       DEVMODE_COPIES |
-                                       DEVMODE_SCALE |
-                                       DEVMODE_PAPERSIZE |
-                                       DEVMODE_ORIENTATION;
-       devmode->orientation          = DMORIENT_PORTRAIT;
-       devmode->papersize            = DMPAPER_LETTER;
-       devmode->paperlength          = 0;
-       devmode->paperwidth           = 0;
-       devmode->scale                = 0x64;
-       devmode->copies               = 1;
-       devmode->defaultsource        = DMBIN_FORMSOURCE;
-       devmode->printquality         = DMRES_HIGH;           /* 0x0258 */
-       devmode->color                = DMRES_MONOCHROME;
-       devmode->duplex               = DMDUP_SIMPLEX;
-       devmode->yresolution          = 0;
-       devmode->ttoption             = DMTT_SUBDEV;
-       devmode->collate              = DMCOLLATE_FALSE;
-       devmode->icmmethod            = 0;
-       devmode->icmintent            = 0;
-       devmode->mediatype            = 0;
-       devmode->dithertype           = 0;
-
-       devmode->logpixels            = 0;
-       devmode->bitsperpel           = 0;
-       devmode->pelswidth            = 0;
-       devmode->pelsheight           = 0;
-       devmode->displayflags         = 0;
-       devmode->displayfrequency     = 0;
-       devmode->reserved1            = 0;
-       devmode->reserved2            = 0;
-       devmode->panningwidth         = 0;
-       devmode->panningheight        = 0;
-
-       devmode->driverextra_data.data = NULL;
-       devmode->driverextra_data.length = 0;
-
-       return devmode;
-}
-
 /**
  * @internal
  *
@@ -295,6 +243,7 @@ static struct spoolss_DeviceMode *winreg_printer_create_default_devmode(TALLOC_C
  */
 static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
                              struct auth_serversupplied_info *server_info,
+                             struct messaging_context *msg_ctx,
                              struct rpc_pipe_client **winreg_pipe,
                              const char *path,
                              const char *key,
@@ -312,8 +261,8 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
        /* create winreg connection */
        status = rpc_pipe_open_internal(mem_ctx,
                                        &ndr_table_winreg.syntax_id,
-                                       rpc_winreg_dispatch,
                                        server_info,
+                                       msg_ctx,
                                        &pipe_handle);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("winreg_printer_openkey: Could not connect to winreg_pipe: %s\n",
@@ -451,7 +400,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
        WERROR result = WERR_OK;
        NTSTATUS status;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -497,7 +446,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                struct spoolss_PrinterEnumValues val;
                struct winreg_ValNameBuf name_buf;
                enum winreg_Type type = REG_NONE;
-               uint8_t *data = NULL;
+               uint8_t *data;
                uint32_t data_size;
                uint32_t length;
                char n = '\0';;
@@ -507,7 +456,10 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                name_buf.length = 0;
 
                data_size = max_valbufsize;
-               data = (uint8_t *) TALLOC(tmp_ctx, data_size);
+               data = NULL;
+               if (data_size) {
+                       data = (uint8_t *) TALLOC(tmp_ctx, data_size);
+               }
                length = 0;
 
                status = rpccli_winreg_EnumValue(pipe_handle,
@@ -517,7 +469,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                                                 &name_buf,
                                                 &type,
                                                 data,
-                                                &data_size,
+                                                data_size ? &data_size : NULL,
                                                 &length,
                                                 &result);
                if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
@@ -549,7 +501,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                val.value_name_len = strlen_m_term(val.value_name) * 2;
 
                val.type = type;
-               val.data_length = data_size;
+               val.data_length = length;
                val.data = NULL;
                if (val.data_length) {
                        val.data = talloc(enum_values, DATA_BLOB);
@@ -557,7 +509,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                                result = WERR_NOMEM;
                                goto error;
                        }
-                       *val.data = data_blob_talloc(enum_values, data, data_size);
+                       *val.data = data_blob_talloc(val.data, data, val.data_length);
                }
 
                enum_values[i] = val;
@@ -611,7 +563,7 @@ static WERROR winreg_printer_enumkeys(TALLOC_CTX *mem_ctx,
        WERROR result = WERR_OK;
        NTSTATUS status;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -844,7 +796,7 @@ static WERROR winreg_printer_write_sz(TALLOC_CTX *mem_ctx,
        if (data == NULL) {
                blob = data_blob_string_const("");
        } else {
-               if (!push_reg_sz(mem_ctx, NULL, &blob, data)) {
+               if (!push_reg_sz(mem_ctx, &blob, data)) {
                        DEBUG(0, ("winreg_printer_write_sz: Could not marshall string %s for %s\n",
                                data, wvalue.name));
                        return WERR_NOMEM;
@@ -958,7 +910,7 @@ static WERROR winreg_printer_query_binary(TALLOC_CTX *mem_ctx,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        goto done;
@@ -988,7 +940,7 @@ static WERROR winreg_printer_query_binary(TALLOC_CTX *mem_ctx,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        result = ntstatus_to_werror(status);
@@ -1029,7 +981,7 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        goto done;
@@ -1065,7 +1017,7 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        result = ntstatus_to_werror(status);
@@ -1092,7 +1044,7 @@ static WERROR winreg_printer_write_multi_sz(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
 
        wvalue.name = value;
-       if (!push_reg_multi_sz(mem_ctx, NULL, &blob, data)) {
+       if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1116,6 +1068,7 @@ static WERROR winreg_printer_write_multi_sz(TALLOC_CTX *mem_ctx,
 
 static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
                                        struct auth_serversupplied_info *server_info,
+                                       struct messaging_context *msg_ctx,
                                        const char *drivername,
                                        const char *architecture,
                                        uint32_t version,
@@ -1137,6 +1090,7 @@ static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(mem_ctx,
                                        server_info,
+                                       msg_ctx,
                                        winreg_pipe,
                                        key_name,
                                        drivername,
@@ -1160,6 +1114,11 @@ static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
+       if (v->data_length != 4) {
+               *dw = 0;
+               return WERR_OK;
+       }
+
        *dw = IVAL(v->data->data, 0);
        return WERR_OK;
 }
@@ -1177,7 +1136,15 @@ static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
-       if (!pull_reg_sz(mem_ctx, NULL, v->data, _str)) {
+       if (v->data_length == 0) {
+               *_str = talloc_strdup(mem_ctx, EMPTY_STRING);
+               if (*_str == NULL) {
+                       return WERR_NOMEM;
+               }
+               return WERR_OK;
+       }
+
+       if (!pull_reg_sz(mem_ctx, v->data, _str)) {
                return WERR_NOMEM;
        }
 
@@ -1198,30 +1165,19 @@ static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
-       if (!pull_reg_multi_sz(mem_ctx, NULL, v->data, array)) {
-               return WERR_NOMEM;
-       }
-
-       return WERR_OK;
-}
-
-static WERROR winreg_enumval_to_blob(TALLOC_CTX *mem_ctx,
-                                    struct spoolss_PrinterEnumValues *v,
-                                    const char *valuename,
-                                    DATA_BLOB *blob)
-{
-       /* just return if it is not the one we are looking for */
-       if (strcmp(valuename, v->value_name) != 0) {
-               return WERR_NOT_FOUND;
+       if (v->data_length == 0) {
+               *array = talloc_array(mem_ctx, const char *, 1);
+               if (*array == NULL) {
+                       return WERR_NOMEM;
+               }
+               *array[0] = NULL;
+               return WERR_OK;
        }
 
-       if (v->type != REG_BINARY) {
-               return WERR_INVALID_DATATYPE;
+       if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
+               return WERR_NOMEM;
        }
 
-       blob->data = v->data->data;
-       blob->length = v->data_length;
-
        return WERR_OK;
 }
 
@@ -1248,7 +1204,7 @@ static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
        }
 
        wvalue.name = value;
-       if (!push_reg_sz(mem_ctx, NULL, &blob, str)) {
+       if (!push_reg_sz(mem_ctx, &blob, str)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1315,7 +1271,7 @@ static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
        }
 
        wvalue.name = value;
-       if (!push_reg_sz(mem_ctx, NULL, &blob, str)) {
+       if (!push_reg_sz(mem_ctx, &blob, str)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1359,6 +1315,7 @@ static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
 
 WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                             struct auth_serversupplied_info *server_info,
+                            struct messaging_context *msg_ctx,
                             const char *servername,
                             const char *sharename)
 {
@@ -1366,18 +1323,16 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
        struct rpc_pipe_client *winreg_pipe = NULL;
        struct policy_handle hive_hnd, key_hnd;
        struct spoolss_SetPrinterInfo2 *info2;
-       struct spoolss_DeviceMode *devmode = NULL;
        struct security_descriptor *secdesc;
        struct winreg_String wkey, wkeyclass;
        const char *path;
-       const char *subkeys[] = { "DsDriver", "DsSpooler", "PrinterDriverData" };
+       const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
        uint32_t i, count = ARRAY_SIZE(subkeys);
-       int snum = lp_servicenumber(sharename);
        uint32_t info2_mask = 0;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -1393,6 +1348,7 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -1414,6 +1370,7 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
        /* Create the main key */
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -1468,6 +1425,119 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                        goto done;
                }
 
+               switch (i) {
+               case 1: {
+                       const char *dnssuffix;
+                       const char *longname;
+                       const char *uncname;
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_PRINTERNAME,
+                                                        sharename);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_SHORTSERVERNAME,
+                                                        global_myname());
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       /* We make the assumption that the netbios name
+                        * is the same as the DNS name since the former
+                        * will be what we used to join the domain
+                        */
+                       dnssuffix = get_mydnsdomname(tmp_ctx);
+                       if (dnssuffix != NULL && dnssuffix[0] != '\0') {
+                               longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix);
+                       } else {
+                               longname = talloc_strdup(tmp_ctx, global_myname());
+                       }
+                       if (longname == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_SERVERNAME,
+                                                        longname);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+                                                 longname, sharename);
+                       if (uncname == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_UNCNAME,
+                                                        uncname);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_VERSIONNUMBER,
+                                                           4);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTSTARTTIME,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTENDTIME,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRIORITY,
+                                                           1);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTKEEPPRINTEDJOBS,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+               } /* case 1 */
+               default:
+                       break;
+               }
+
                if (is_valid_policy_hnd(&key_hnd)) {
                        rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
                }
@@ -1478,7 +1548,16 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       info2->printername = sharename;
+       if (servername != NULL) {
+               info2->printername = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+                                                    servername, sharename);
+       } else {
+               info2->printername = sharename;
+       }
+       if (info2->printername == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
        info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
 
        info2->sharename = sharename;
@@ -1511,31 +1590,24 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
        info2->defaultpriority = 1;
        info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
 
-       /* info2->setuptime = (uint32_t) time(NULL); */
-
-       if (lp_default_devmode(snum)) {
-               devmode = winreg_printer_create_default_devmode(tmp_ctx,
-                                                               info2->printername);
-               if (devmode == NULL) {
-                       result = WERR_NOMEM;
-                       goto done;
-               }
-
-               info2_mask |= SPOOLSS_PRINTER_INFO_DEVMODE;
-       }
-
        result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
        if (!W_ERROR_IS_OK(result)) {
                goto done;
        }
        info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
 
+       /*
+        * Don't write a default Device Mode to the registry! The Device Mode is
+        * only written to disk with a SetPrinter level 2 or 8.
+        */
+
        result = winreg_update_printer(tmp_ctx,
                                       server_info,
+                                      msg_ctx,
                                       sharename,
                                       info2_mask,
                                       info2,
-                                      devmode,
+                                      NULL,
                                       secdesc);
 
 done:
@@ -1554,6 +1626,7 @@ done:
 
 WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
                             struct auth_serversupplied_info *server_info,
+                            struct messaging_context *msg_ctx,
                             const char *sharename,
                             uint32_t info2_mask,
                             struct spoolss_SetPrinterInfo2 *info2,
@@ -1563,13 +1636,14 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        struct rpc_pipe_client *winreg_pipe = NULL;
        struct policy_handle hive_hnd, key_hnd;
+       int snum = lp_servicenumber(sharename);
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
        char *path;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -1585,6 +1659,7 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -1656,7 +1731,20 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
        }
 
        if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
-               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, devmode,
+               /*
+                * Some client drivers freak out if there is a NULL devmode
+                * (probably the driver is not checking before accessing
+                * the devmode pointer)   --jerry
+                */
+               if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
+                       result = spoolss_create_default_devmode(tmp_ctx,
+                                                               info2->printername,
+                                                               &devmode);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+               }
+               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
                                (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
@@ -1779,19 +1867,11 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
                                goto done;
                        }
                }
-               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, secdesc,
-                               (ndr_push_flags_fn_t) ndr_push_security_descriptor);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       DEBUG(0, ("winreg_update_printer: Failed to marshall security descriptor\n"));
-                       result = WERR_NOMEM;
-                       goto done;
-               }
-
-               result = winreg_printer_write_binary(tmp_ctx,
-                                                    winreg_pipe,
-                                                    &key_hnd,
-                                                    "Security",
-                                                    blob);
+               result = winreg_set_printer_secdesc(tmp_ctx,
+                                                   server_info,
+                                                   msg_ctx,
+                                                   sharename,
+                                                   secdesc);
                if (!W_ERROR_IS_OK(result)) {
                        goto done;
                }
@@ -1878,6 +1958,7 @@ done:
 
 WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                          struct auth_serversupplied_info *server_info,
+                         struct messaging_context *msg_ctx,
                          const char *servername,
                          const char *printer,
                          struct spoolss_PrinterInfo2 **pinfo2)
@@ -1890,13 +1971,14 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
        struct spoolss_PrinterEnumValues *v;
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
+       int snum = lp_servicenumber(printer);
        uint32_t num_values = 0;
        uint32_t i;
        char *path;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -1909,6 +1991,7 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -1917,7 +2000,7 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
                          path, win_errstr(result)));
                goto done;
        }
@@ -1939,17 +2022,17 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       info2->servername     = EMPTY_STRING;
-       info2->printername    = EMPTY_STRING;
-       info2->sharename      = EMPTY_STRING;
-       info2->portname       = EMPTY_STRING;
-       info2->drivername     = EMPTY_STRING;
-       info2->comment        = EMPTY_STRING;
-       info2->location       = EMPTY_STRING;
-       info2->sepfile        = EMPTY_STRING;
-       info2->printprocessor = EMPTY_STRING;
-       info2->datatype       = EMPTY_STRING;
-       info2->parameters     = EMPTY_STRING;
+       FILL_STRING(info2, EMPTY_STRING, info2->servername);
+       FILL_STRING(info2, EMPTY_STRING, info2->printername);
+       FILL_STRING(info2, EMPTY_STRING, info2->sharename);
+       FILL_STRING(info2, EMPTY_STRING, info2->portname);
+       FILL_STRING(info2, EMPTY_STRING, info2->drivername);
+       FILL_STRING(info2, EMPTY_STRING, info2->comment);
+       FILL_STRING(info2, EMPTY_STRING, info2->location);
+       FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
+       FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
+       FILL_STRING(info2, EMPTY_STRING, info2->datatype);
+       FILL_STRING(info2, EMPTY_STRING, info2->parameters);
 
        if (servername != NULL && servername[0] != '\0') {
                info2->servername = talloc_asprintf(info2, "\\\\%s", servername);
@@ -1966,15 +2049,6 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                                              v,
                                              "Name",
                                              &info2->printername);
-               if (W_ERROR_IS_OK(result) && info2->servername[0] != '\0') {
-                       char *p = talloc_asprintf(info2, "%s\\%s",
-                                                 info2->servername,
-                                                 info2->printername);
-                       if (p == NULL) {
-                               result = WERR_NOMEM;
-                       }
-                       info2->printername = p;
-               }
                CHECK_ERROR(result);
 
                result = winreg_enumval_to_sz(info2,
@@ -2072,62 +2146,95 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                                                 "StartTime",
                                                 &info2->starttime);
                CHECK_ERROR(result);
+       }
 
-               result = winreg_enumval_to_blob(info2,
-                                               v,
-                                               "Default DevMode",
-                                               &blob);
-               if (W_ERROR_IS_OK(result)) {
-                       info2->devmode = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-                       if (info2->devmode == NULL) {
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
-                       ndr_err = ndr_pull_struct_blob(&blob,
-                                                      info2,
-                                                      NULL,
-                                                      info2->devmode,
-                                                      (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+       if (!W_ERROR_IS_OK(result)) {
+               DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
+                                       "for %s: %s\n",
+                                       v->value_name,
+                                       win_errstr(result)));
+               goto done;
+       }
+
+       /* Create the printername */
+       if (info2->servername != NULL && info2->servername[0] != '\0') {
+               if (lp_force_printername(snum)) {
+                       const char *p = talloc_asprintf(info2, "%s\\%s",
+                                                       info2->servername,
+                                                       info2->sharename);
+                               if (p == NULL) {
+                                       result = WERR_NOMEM;
+                                       goto done;
+                               }
+                               info2->printername = p;
+               } else {
+                       char *p = talloc_asprintf(info2, "%s\\%s",
+                                                 info2->servername,
+                                                 info2->printername);
+                       if (p == NULL) {
                                result = WERR_NOMEM;
                                goto done;
                        }
+                       info2->printername = p;
                }
-               CHECK_ERROR(result);
+       }
 
-               result = winreg_enumval_to_blob(info2,
-                                               v,
-                                               "Security",
-                                               &blob);
-               if (W_ERROR_IS_OK(result)) {
-                       info2->secdesc = talloc_zero(mem_ctx, struct spoolss_security_descriptor);
-                       if (info2->secdesc == NULL) {
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
-                       ndr_err = ndr_pull_struct_blob(&blob,
-                                                      mem_ctx,
-                                                      NULL,
-                                                      info2->secdesc,
-                                                      (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               DEBUG(0, ("winreg_get_printer: Failed to unmarshall security descriptor\n"));
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
+       /* Construct the Device Mode */
+       result = winreg_printer_query_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Default DevMode",
+                                            &blob);
+       if (W_ERROR_IS_OK(result)) {
+               info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
+               if (info2->devmode == NULL) {
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+               ndr_err = ndr_pull_struct_blob(&blob,
+                                              info2->devmode,
+                                              info2->devmode,
+                                              (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+       }
+
+       if (info2->devmode == NULL && lp_default_devmode(snum)) {
+               result = spoolss_create_default_devmode(info2,
+                                                       info2->printername,
+                                                       &info2->devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2->devmode != NULL) {
+               info2->devmode->devicename = talloc_strdup(info2->devmode,
+                                                          info2->printername);
+               if (info2->devmode->devicename == NULL) {
+                       DEBUG(0, ("winreg_get_printer: Failed to set devicename\n"));
+                       result = WERR_NOMEM;
+                       goto done;
                }
-               CHECK_ERROR(result);
        }
 
+       result = winreg_get_printer_secdesc(info2,
+                                           server_info,
+                                           msg_ctx,
+                                           printer,
+                                           &info2->secdesc);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
-                                       "for %s: %s\n",
-                                       v->value_name,
-                                       win_errstr(result)));
                goto done;
        }
 
+       /* Fix for OS/2 drivers. */
+       if (get_remote_arch() == RA_OS2) {
+               spoolss_map_to_os2_driver(info2, &info2->drivername);
+       }
+
        if (pinfo2) {
                *pinfo2 = talloc_move(mem_ctx, &info2);
        }
@@ -2147,9 +2254,293 @@ done:
        return result;
 }
 
+WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+                                 struct auth_serversupplied_info *server_info,
+                                 struct messaging_context *msg_ctx,
+                                 const char *sharename,
+                                 struct spoolss_security_descriptor **psecdesc)
+{
+       struct spoolss_security_descriptor *secdesc;
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       enum ndr_err_code ndr_err;
+       const char *path;
+       DATA_BLOB blob;
+       TALLOC_CTX *tmp_ctx;
+       WERROR result;
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       path = winreg_printer_data_keyname(tmp_ctx, sharename);
+       if (path == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_NOMEM;
+       }
+
+       ZERO_STRUCT(hive_hnd);
+       ZERO_STRUCT(key_hnd);
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       server_info,
+                                       msg_ctx,
+                                       &winreg_pipe,
+                                       path,
+                                       "",
+                                       false,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+                       goto create_default;
+               }
+               goto done;
+       }
+
+       result = winreg_printer_query_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            &blob);
+       if (!W_ERROR_IS_OK(result)) {
+               if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+                       goto create_default;
+               }
+               goto done;
+       }
+
+       secdesc = talloc_zero(tmp_ctx, struct spoolss_security_descriptor);
+       if (secdesc == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+       ndr_err = ndr_pull_struct_blob(&blob,
+                                      secdesc,
+                                      secdesc,
+                                      (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_get_secdesc: Failed to unmarshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       if (psecdesc) {
+               *psecdesc = talloc_move(mem_ctx, &secdesc);
+       }
+
+       result = WERR_OK;
+       goto done;
+
+create_default:
+       result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       /* If security descriptor is owned by S-1-1-0 and winbindd is up,
+          this security descriptor has been created when winbindd was
+          down.  Take ownership of security descriptor. */
+       if (sid_equal(secdesc->owner_sid, &global_sid_World)) {
+               struct dom_sid owner_sid;
+
+               /* Change sd owner to workgroup administrator */
+
+               if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
+                       struct spoolss_security_descriptor *new_secdesc;
+                       size_t size;
+
+                       /* Create new sd */
+                       sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
+
+                       new_secdesc = make_sec_desc(tmp_ctx,
+                                                   secdesc->revision,
+                                                   secdesc->type,
+                                                   &owner_sid,
+                                                   secdesc->group_sid,
+                                                   secdesc->sacl,
+                                                   secdesc->dacl,
+                                                   &size);
+
+                       if (new_secdesc == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       /* Swap with other one */
+                       secdesc = new_secdesc;
+               }
+       }
+
+       ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, secdesc,
+                       (ndr_push_flags_fn_t) ndr_push_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       result = winreg_printer_write_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            blob);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       if (psecdesc) {
+               *psecdesc = talloc_move(mem_ctx, &secdesc);
+       }
+
+       result = WERR_OK;
+done:
+       if (winreg_pipe != NULL) {
+               if (is_valid_policy_hnd(&key_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+               }
+               if (is_valid_policy_hnd(&hive_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return result;
+}
+
+WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+                                 struct auth_serversupplied_info *server_info,
+                                 struct messaging_context *msg_ctx,
+                                 const char *sharename,
+                                 const struct spoolss_security_descriptor *secdesc)
+{
+       const struct spoolss_security_descriptor *new_secdesc = secdesc;
+       struct spoolss_security_descriptor *old_secdesc;
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       enum ndr_err_code ndr_err;
+       const char *path;
+       DATA_BLOB blob;
+       TALLOC_CTX *tmp_ctx;
+       WERROR result;
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       path = winreg_printer_data_keyname(tmp_ctx, sharename);
+       if (path == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_NOMEM;
+       }
+
+       /*
+        * The old owner and group sids of the security descriptor are not
+        * present when new ACEs are added or removed by changing printer
+        * permissions through NT.  If they are NULL in the new security
+        * descriptor then copy them over from the old one.
+        */
+       if (!secdesc->owner_sid || !secdesc->group_sid) {
+               struct dom_sid *owner_sid, *group_sid;
+               struct security_acl *dacl, *sacl;
+               size_t size;
+
+               result = winreg_get_printer_secdesc(tmp_ctx,
+                                                   server_info,
+                                                   msg_ctx,
+                                                   sharename,
+                                                   &old_secdesc);
+               if (!W_ERROR_IS_OK(result)) {
+                       talloc_free(tmp_ctx);
+                       return result;
+               }
+
+               /* Pick out correct owner and group sids */
+               owner_sid = secdesc->owner_sid ?
+                           secdesc->owner_sid :
+                           old_secdesc->owner_sid;
+
+               group_sid = secdesc->group_sid ?
+                           secdesc->group_sid :
+                           old_secdesc->group_sid;
+
+               dacl = secdesc->dacl ?
+                      secdesc->dacl :
+                      old_secdesc->dacl;
+
+               sacl = secdesc->sacl ?
+                      secdesc->sacl :
+                      old_secdesc->sacl;
+
+               /* Make a deep copy of the security descriptor */
+               new_secdesc = make_sec_desc(tmp_ctx,
+                                           secdesc->revision,
+                                           secdesc->type,
+                                           owner_sid,
+                                           group_sid,
+                                           sacl,
+                                           dacl,
+                                           &size);
+               if (new_secdesc == NULL) {
+                       talloc_free(tmp_ctx);
+                       return WERR_NOMEM;
+               }
+       }
+
+       ZERO_STRUCT(hive_hnd);
+       ZERO_STRUCT(key_hnd);
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       server_info,
+                                       msg_ctx,
+                                       &winreg_pipe,
+                                       path,
+                                       "",
+                                       false,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+       ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, new_secdesc,
+                       (ndr_push_flags_fn_t) ndr_push_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       result = winreg_printer_write_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            blob);
+
+done:
+       if (winreg_pipe != NULL) {
+               if (is_valid_policy_hnd(&key_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+               }
+               if (is_valid_policy_hnd(&hive_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return result;
+}
+
 /* Set printer data over the winreg pipe. */
 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
+                                struct messaging_context *msg_ctx,
                                 const char *printer,
                                 const char *key,
                                 const char *value,
@@ -2166,7 +2557,7 @@ WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2184,6 +2575,7 @@ WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
                        key, value, access_mask, printer));
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2234,6 +2626,7 @@ done:
 /* Get printer data over a winreg pipe. */
 WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
+                                struct messaging_context *msg_ctx,
                                 const char *printer,
                                 const char *key,
                                 const char *value,
@@ -2254,7 +2647,7 @@ WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2270,6 +2663,7 @@ WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2278,7 +2672,7 @@ WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2358,6 +2752,7 @@ done:
 /* Enumerate on the values of a given key and provide the data. */
 WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
                                  struct auth_serversupplied_info *server_info,
+                                 struct messaging_context *msg_ctx,
                                  const char *printer,
                                  const char *key,
                                  uint32_t *pnum_values,
@@ -2374,7 +2769,7 @@ WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2387,6 +2782,7 @@ WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2395,7 +2791,7 @@ WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2434,6 +2830,7 @@ done:
 /* Delete printer data over a winreg pipe. */
 WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
                                    struct auth_serversupplied_info *server_info,
+                                   struct messaging_context *msg_ctx,
                                    const char *printer,
                                    const char *key,
                                    const char *value)
@@ -2448,7 +2845,7 @@ WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2464,6 +2861,7 @@ WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2511,6 +2909,7 @@ done:
 /* Enumerate on the subkeys of a given key and provide the data. */
 WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
                               struct auth_serversupplied_info *server_info,
+                              struct messaging_context *msg_ctx,
                               const char *printer,
                               const char *key,
                               uint32_t *pnum_subkeys,
@@ -2527,7 +2926,7 @@ WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2543,6 +2942,7 @@ WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2551,7 +2951,7 @@ WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2590,6 +2990,7 @@ done:
 /* Delete a key with subkeys of a given printer. */
 WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
+                                struct messaging_context *msg_ctx,
                                 const char *printer,
                                 const char *key)
 {
@@ -2601,7 +3002,7 @@ WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2614,6 +3015,7 @@ WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        key,
@@ -2677,6 +3079,7 @@ done:
 
 WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
                                      struct auth_serversupplied_info *server_info,
+                                     struct messaging_context *msg_ctx,
                                      const char *printer)
 {
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -2686,7 +3089,7 @@ WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2702,6 +3105,7 @@ WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -2741,6 +3145,7 @@ done:
 
 WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
                                   struct auth_serversupplied_info *server_info,
+                                  struct messaging_context *msg_ctx,
                                   const char *printer,
                                   uint32_t *pchangeid)
 {
@@ -2752,7 +3157,7 @@ WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2768,6 +3173,7 @@ WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        path,
                                        "",
@@ -2776,12 +3182,13 @@ WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
                          path, win_errstr(result)));
                goto done;
        }
 
-       DEBUG(0, ("winreg_printer_get_changeid: get changeid from %s\n", path));
+       DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
+
        result = winreg_printer_query_dword(tmp_ctx,
                                            winreg_pipe,
                                            &key_hnd,
@@ -2819,6 +3226,7 @@ done:
 
 WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
                               struct auth_serversupplied_info *server_info,
+                              struct messaging_context *msg_ctx,
                               struct spoolss_AddFormInfo1 *form)
 {
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -2833,7 +3241,7 @@ WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2843,6 +3251,7 @@ WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        TOP_LEVEL_CONTROL_FORMS_KEY,
                                        "",
@@ -2856,7 +3265,8 @@ WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       result = winreg_printer_enumforms1(tmp_ctx, server_info, &num_info, &info);
+       result = winreg_printer_enumforms1(tmp_ctx, server_info, msg_ctx,
+                                          &num_info, &info);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
                          TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
@@ -2919,6 +3329,7 @@ done:
 
 WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
+                                struct messaging_context *msg_ctx,
                                 uint32_t *pnum_info,
                                 union spoolss_FormInfo **pinfo)
 {
@@ -2933,7 +3344,7 @@ WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2943,6 +3354,7 @@ WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       msg_ctx,
                                        &winreg_pipe,
                                        TOP_LEVEL_CONTROL_FORMS_KEY,
                                        "",
@@ -3006,7 +3418,7 @@ WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
                val.info1.area.right  = IVAL(enum_values[i].data->data, 16);
                val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
                /* skip form index      IVAL(enum_values[i].data->data, 24)));*/
-               val.info1.flags       = IVAL(enum_values[i].data->data, 28);
+               val.info1.flags       = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
 
                info[i + num_builtin] = val;
        }
@@ -3051,7 +3463,7 @@ WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3061,6 +3473,7 @@ WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       smbd_messaging_context(),
                                        &winreg_pipe,
                                        TOP_LEVEL_CONTROL_FORMS_KEY,
                                        "",
@@ -3136,7 +3549,7 @@ WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3146,6 +3559,7 @@ WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       smbd_messaging_context(),
                                        &winreg_pipe,
                                        TOP_LEVEL_CONTROL_FORMS_KEY,
                                        "",
@@ -3241,7 +3655,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3251,6 +3665,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
 
        result = winreg_printer_openkey(tmp_ctx,
                                        server_info,
+                                       smbd_messaging_context(),
                                        &winreg_pipe,
                                        TOP_LEVEL_CONTROL_FORMS_KEY,
                                        "",
@@ -3259,7 +3674,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_printer_getform1: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
                          TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
                goto done;
        }
@@ -3329,7 +3744,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
        r->area.right  = IVAL(data_in, 16);
        r->area.bottom = IVAL(data_in, 20);
        /* skip index    IVAL(data_in, 24)));*/
-       r->flags       = IVAL(data_in, 28);
+       r->flags       = (enum spoolss_FormFlags) IVAL(data_in, 28);
 
        result = WERR_OK;
 done:
@@ -3368,13 +3783,14 @@ WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
 
        result = winreg_printer_opendriver(tmp_ctx,
                                           server_info,
+                                          smbd_messaging_context(),
                                           info8.driver_name,
                                           info8.architecture,
                                           info8.version,
@@ -3592,7 +4008,7 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(key_hnd);
        ZERO_STRUCT(i8);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3601,6 +4017,7 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
                /* look for Win2k first and then for NT4 */
                result = winreg_printer_opendriver(tmp_ctx,
                                                   server_info,
+                                                  smbd_messaging_context(),
                                                   driver_name,
                                                   architecture,
                                                   3,
@@ -3611,6 +4028,7 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
                if (!W_ERROR_IS_OK(result)) {
                        result = winreg_printer_opendriver(tmp_ctx,
                                                           server_info,
+                                                          smbd_messaging_context(),
                                                           driver_name,
                                                           architecture,
                                                           2,
@@ -3623,6 +4041,7 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
                /* ok normal case */
                result = winreg_printer_opendriver(tmp_ctx,
                                                   server_info,
+                                                  smbd_messaging_context(),
                                                   driver_name,
                                                   architecture,
                                                   driver_version,
@@ -3670,35 +4089,20 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       info8->config_file = EMPTY_STRING;
-       info8->data_file = EMPTY_STRING;
-       info8->default_datatype = EMPTY_STRING;
-       info8->driver_path = EMPTY_STRING;
-       info8->hardware_id = EMPTY_STRING;
-       info8->help_file = EMPTY_STRING;
-       info8->inf_path = EMPTY_STRING;
-       info8->manufacturer_name = EMPTY_STRING;
-       info8->manufacturer_url = EMPTY_STRING;
-       info8->monitor_name = EMPTY_STRING;
-       info8->print_processor = EMPTY_STRING;
-       info8->provider = EMPTY_STRING;
-       info8->vendor_setup = EMPTY_STRING;
-
-       info8->color_profiles = empty_string_array;
-       info8->core_driver_dependencies = EMPTY_STRING_ARRAY;
-       info8->dependent_files = EMPTY_STRING_ARRAY;
-       info8->previous_names = EMPTY_STRING_ARRAY;
-
        result = WERR_OK;
 
        for (i = 0; i < num_values; i++) {
                const char *tmp_str;
+               uint32_t tmp = 0;
 
                v = &enum_values[i];
 
                result = winreg_enumval_to_dword(info8, v,
                                                 "Version",
-                                                &info8->version);
+                                                &tmp);
+               if (NT_STATUS_IS_OK(result)) {
+                       info8->version = (enum spoolss_DriverOSVersion) tmp;
+               }
                CHECK_ERROR(result);
 
                result = winreg_enumval_to_sz(info8, v,
@@ -3866,7 +4270,7 @@ WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(hive_hnd);
        ZERO_STRUCT(key_hnd);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3874,6 +4278,7 @@ WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
        /* test that the key exists */
        result = winreg_printer_opendriver(tmp_ctx,
                                           server_info,
+                                          smbd_messaging_context(),
                                           info8->driver_name,
                                           info8->architecture,
                                           version,
@@ -3957,7 +4362,7 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(hive_hnd);
        ZERO_STRUCT(key_hnd);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3966,6 +4371,7 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
         * parent of all drivers for this architecture and version */
        result = winreg_printer_opendriver(tmp_ctx,
                                           server_info,
+                                          smbd_messaging_context(),
                                           NULL,
                                           architecture,
                                           version,