CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
英特尔®游戏设计大赛100美元现金周周送 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

AddPrinterDriver API哪位老大能给个详细的sample

楼主chinahu3000()2003-08-02 09:53:36 在 VC/MFC / 基础类 提问

AddPrinterDriver   API哪位老大能给个详细的sample 问题点数:0、回复次数:7Top

1 楼chinahu3000()回复于 2003-08-02 14:17:13 得分 0

upTop

2 楼taianmonkey()回复于 2003-08-02 14:26:36 得分 0

/*---------------------------------------------------------------  
  THIS   CODE   AND   INFORMATION   IS   PROVIDED   "AS   IS"   WITHOUT   WARRANTY   OF  
  ANY   KIND,   EITHER   EXPRESSED   OR   IMPLIED,   INCLUDING   BUT   NOT   LIMITED  
  TO   THE   IMPLIED   WARRANTIES   OF   MERCHANTABILITY   AND/OR   FITNESS   FOR   A  
  PARTICULAR   PURPOSE.  
   
  Copyright   (C)   2001     Microsoft   Corporation.     All   rights   reserved.  
   
  DrvSrv.cpp  
   
  Defines   the   entry   point   and   exported   functions   for   the   DLL   application.  
   
  This   DLL   exports:  
   
  Install  
  This   is   the   RunDLL32   entry   point   included   just   to   support   RunDLL32  
   
  InstallDriver  
  This   is   the   function   that   does   all   the   work  
   
  The   exported   functions   are   exported   via   .DEF   file   so   that   they  
  can   be   called   easily   from   Visual   Basic   and   RunDLL32.  
   
  History:  
  4/37/2001 Wrote   it. -jcd  
  5/2/2001 1rst   Publication -jcd  
  ---------------------------------------------------------------*/  
   
   
  #include   "stdafx.h"  
  #include   "windows.h"  
  #include   "winspool.h"  
  #include   "DrvSrv.h"  
   
  BOOL   APIENTRY   DllMain(   HANDLE   hModule,    
                                                DWORD     ul_reason_for_call,    
                                                LPVOID   lpReserved  
    )  
  {  
          switch   (ul_reason_for_call)  
  {  
  case   DLL_PROCESS_ATTACH:  
  case   DLL_THREAD_ATTACH:  
  case   DLL_THREAD_DETACH:  
  case   DLL_PROCESS_DETACH:  
  break;  
          }  
          return   TRUE;  
  }  
   
   
  /*  
  Function:   Install  
   
  RunDll32   entry   point   per:  
   
  Q164787   INFO:   The   Windows   95   Rundll   and   Rundll32   Interface  
   
  Remarks:  
  usage:   RunDLL32   drvsrv,Install   "\\[server]\[share]"  
  */  
  void   CALLBACK   Install(HWND   hwnd,   HINSTANCE   hinst,   LPSTR   lpszCmdLine,   int   nCmdShow)  
  {  
  InstallDriver(lpszCmdLine);  
  }  
   
   
  /*  
  Function:   StripQuotes  
   
  Parameters:  
  IN/OUT str -   the   string   from   which   leading   and   trailing   quotes   are   to   be    
  removed.  
   
  Remarks:  
  This   code   assumes   that   if   the   first   char   is   not   a   quote,   the   string  
  should   be   left   alone.  
  The   work   is   performed   by   moving   the   char's   of   the   string   forward   to  
  overwrite   the   leading   quote.  
  It   trims   any   trailing   quote   by   overwritting   the   quote   char   with   a    
  NULL   terminator.  
  Worst   case,   the   string   length   shrinks   by   a   count   of   2   chars.  
  A   string   with   a   leading   quote   but   no   trailing   quote   is   valid.  
    */  
  void   StripQuotes(char   *str)  
  {  
  int end;  
   
  //   if   leading   quotes,   then   we   have   work   to   do  
  if   (str[0]   ==   '"')  
  {  
  //   strip   leading   quote  
  lstrcpy(str,   &str[1]);  
   
  //   look   for   trailing   quote   and   strip   it   too   if   necessary  
  end   =   lstrlen(str)-1;  
  if   (str[end]   ==   '"')  
  str[end]   =   0;  
  }  
   
  }  
   
  /*  
  Function:   TrimToServer  
   
  Parameters:  
  IN/OUT pszUNC -   the   UNC   path  
   
  Remarks:  
  This   function   assumes   the   string   is   of   the   form   "\\xxxx\ssss".  
  It   truncates   pszUNC   to   the   form   "\\xxx"  
    */  
  void   TrimToServer(char   *pszUNC)  
  {  
  int   ServerLen   =   strcspn(&pszUNC[2],   "\\");  
  pszUNC[ServerLen   +   2]   =   '\0';  
  }  
   
   
  /*  
  Function:   GetDriverInfo  
   
  Parameters:  
  IN pszUNC -   the   UNC   path   to   the   printer   share   on   a   Windows   NT   or   2000   print   server  
  OUT ppInfo -   pointer   to   a   pointer   variable   that   receives   the   info  
   
  Remarks:  
  Caller   must   free   the   buffer   at   *ppInfo   by   using   "delete   (char   *)   *ppInfo;"  
    */  
  BOOL   GetDriverInfo(char   *pszUNC,   DRIVER_INFO_3   **ppInfo)  
  {  
  HANDLE hPrinter   =   INVALID_HANDLE_VALUE;  
  DRIVER_INFO_3 *pDI3   =   NULL;  
  DWORD dwError   =   0;  
  char *pEnv   =   NULL; //   We'll   never   use   this   on   9x   -   must   always   be   NULL  
  DWORD cbNeeded;  
   
   
  if   (!OpenPrinter(pszUNC,   &hPrinter,   NULL))  
  {  
  //   hmm,   path   to   alleged   printer   must   be   wrong  
  //   or   if   this   somehow   got   executed   on   NT,   the   user   account  
  //   does   not   have   access   to   the   printer   and/or   we   needed   the  
  //   third   parameter.  
  goto   bail;  
  }  
   
  //   We   expect   the   following   call   to   fail   so   it   can   tell   us    
  //   how   big   the   buffer   should   be.  
  GetPrinterDriver(hPrinter,   pEnv,   3,   (LPBYTE)NULL,   0,   &cbNeeded);  
  dwError   =   GetLastError();  
   
  if   (dwError   !=   ERROR_INSUFFICIENT_BUFFER)  
  {  
  //   OK,   this   is   bad.   We   know   the   path   is   valid   to   somthing    
  //   since   we   succeeded   with   OpenPrinter.  
  //   But   it   sure   isn't   a   printer   share,   or   something   worse.  
  goto   bail;  
  }  
   
  //   we   know   how   big   now,   proceed  
  pDI3   =   (DRIVER_INFO_3   *)new   char[cbNeeded];  
  if   (!GetPrinterDriver(hPrinter,   pEnv,   3,   (LPBYTE)pDI3,   cbNeeded,   &cbNeeded))  
  {  
  //   This   time   if   it   fails,   its   for   good.  
  //   It   really   can't   be   an   insufficient   buffer   error.   We've   done   that   already.  
  //   Could   have   been   a   network   error.  
  //   System   might   be   unstable.  
  //   Something   happened   to   the   printer   install.  
  //   ...  
  //   But   we   are   done.  
  goto   bail;  
  }  
   
  //   Now   we   have   the   goods,   send   them   back   to   the   caller.  
  *ppInfo   =   pDI3;  
  pDI3   =   NULL; //   We   do   not   own   the   buffer   anymore.  
   
  //   Done   with   the   printer   or   the   printer   share  
  ClosePrinter(hPrinter);  
   
  return   TRUE;  
   
  bail:  
  delete   ((char   *)   pDI3); //   delete   by   the   same   datatype   as   allocated  
  ClosePrinter(hPrinter);  
  return   FALSE;  
   
  }  
  Top

3 楼taianmonkey()回复于 2003-08-02 14:27:45 得分 0

 
  /*  
  Function:   GetDriverServerPath9x  
   
  Parameters:  
  IN pszUNC -   the   UNC   path   to   the   printer   share   on   Windows   NT   or   2000  
  OUT pszDest -   pointer   to   a   string   buffer   to   receive   the   path.  
  IN cChar -   size   of   pszDest   string   buffer   in   characters.  
   
  Remarks:  
  The   function   combines   the   "known"   path   to   the   driver   files   on   NT/2000  
  with   the   name   of   the   NT/2000   print   server   passed   in   by   pszUNC.  
  Nominally,   we   should   have   needed   to   use   GetPrinterDriverDirectory   but  
  on   Windows   9x,   this   function   works   only   on   the   local   machine.  
   
  print$   is   the   invisible   share   used   for   printer   driver   files.  
  Win40   is   the   "Environment"   directory   that   correlates   to   the    
  "Windows   4.0"   environment   string   that   means   Windows   9x.  
  0   is   the   directory   that   represents   the   driver   architecture   for   9x   print  
  drivers.  
   
  A   function   customized   for   Windows   NT/2000   would   need   to   be   written   if  
  this   technique   would   be   used   on   such   a   client.   Fortunately,   with   NT    
  Printer   Connections,   all   of   this   is   unnecessary.   Just   Call    
  AddPrinterConnection().  
    */  
  BOOL   GetDriverServerPath9x(const   char   *pszUNC,   char   *pszDest,   const   int   cChar)  
  {  
  ZeroMemory(pszDest,   cChar);  
  lstrcpyn(pszDest,   pszUNC,   cChar);  
  TrimToServer(pszDest);  
  lstrcat(pszDest,   "\\print$\\Win40\\0"); //   always   this   way   for   9x   clients  
   
  return   TRUE;  
  }  
   
  /*  
  Function:   DuplicateFile  
   
  Parameters:  
  IN pszFile -   the   filename   to   be   duplicated  
  IN pszDestPath -   the   destination   path   to   write   the   copy  
  IN pszSrcPath -   the   source   path   to   the   existing   file  
  IN fOverwrite -   the   whether   to   try   to   overwrite   the   file  
   
  Remarks:  
  This   function   combines   the   CopyFile   operation   with   the   Full   path    
  creation   work   to   provide   a   simple   interface   for   replicating   a   file   by  
  name   from   one   place   to   another.  
   
  Very   handy   for   copying   down   driver   files   from   a   share.  
    */  
  BOOL   DuplicateFile(const   char   *pszFile,   const   char   *pszDestPath,   const   char   *pszSrcPath,   const   BOOL   fOverwrite)  
  {  
  char   szSrc[MAX_PATH];  
  char   szDest[MAX_PATH];  
   
  lstrcpy(szSrc,   pszSrcPath);  
  lstrcat(szSrc,   "\\");  
  lstrcat(szSrc,   pszFile);  
   
  lstrcpy(szDest,   pszDestPath);  
  lstrcat(szDest,   "\\");  
  lstrcat(szDest,   pszFile);  
   
  return   CopyFile(szSrc,   szDest,   !fOverwrite);  
  }  
   
  /*  
  Function:   ReferenceFileName  
   
  Parameters:  
  IN pszPath -   the   path   containing   the   file   name  
   
  Remarks:  
  A   handy   utility   for   getting   a   string   pointer   to   a   filename   in   a   path  
  when   it   is   not   necessary   to   isolate   the   filename   from   the   path   in   the  
  string   buffer.  
   
  Used   for   calls   to   DuplicateFile.  
    */  
  const   char   *ReferenceFileName(const   char   *pszPath)  
  {  
  /*   look   for   the   leading   backslash   before   the   filename  
        if   NULL   is   returned,   there   isn't   one   and   the   pszPath  
        is   the   filename.  
   
        if   we   found   the   backslash,   adjust   the   pointer   to   the   start  
        of   the   filename.  
    */  
  const   char   *pszFile   =   strrchr(pszPath,   '\\');  
  if   (!pszFile)  
  /*   Note   that   we   pass   through   NULL   here   if   we   are   given   NULL   */  
  pszFile   =   pszPath;  
  else  
  pszFile++;  
   
  return   pszFile;  
  }  
   
   
  /*  
  Function:   CopyDriverFiles  
   
  Parameters:  
  IN pDrvInfo -   the   driver   info   structure   that   contains   the   list   of   files  
  IN pszDest -   destination   path   for   the   driver   files  
  IN pszSrc -   source   path   for   the   driver   files  
   
  Returns:   TRUE   if   all   of   the   drive   files   were   copied.  
   
  Remarks:  
  Copies   driver   files   listed   in   a   DRIVER_INFO_3   structure   from   pszDest  
  to   pszSrc.   The   path   parameters   should   not   contain   trailing   backslashes.  
   
  If   there   is   a   file   listed   in   a   field   of   DRIVER_INFO_3,    
  we   try   to   copy   it.  
   
  If   it   exists,   we   copy   over   it.   The   assumption   being   this   is   the   right    
  thing   to   do   because   the   file   is   compatible   with   the   one   overwritten.  
  If   it   exists   and   is   in   use,   the   copy   will   fail   and   so   will   we.  
   
  This   function   behaves   conservatively   for   failures.   If   copying   of   one    
  file   fails   for   any   reason,   it   quits   and   returns   FALSE.  
   
  The   function   could   be   modified   to   check   for   the   case   where   the   copy    
  failed   because   the   driver   file   already   existed   and   is   in   use.   If   the    
  file   is   compatible,   we   could   use   it   and   allow   things   to   proceed.  
   
    */  
  BOOL   CopyDriverFiles(const   DRIVER_INFO_3   *pDrvInfo,   const   char   *pszDest,   const   char   *pszSrc)  
  {  
  const   char   *pszFile;  
  char   *pszDepFiles;  
   
  /*   Copy   the   driver   */  
  pszFile   =   ReferenceFileName(pDrvInfo->pDriverPath);  
  if   (pszFile)  
  {  
  if   (!DuplicateFile(pszFile,   pszDest,   pszSrc,   TRUE))  
  goto   bail;  
  }  
   
  /*   Copy   the   configuration   file   */  
  pszFile   =   ReferenceFileName(pDrvInfo->pConfigFile);  
  if   (pszFile)  
  {  
  if   (!DuplicateFile(pszFile,   pszDest,   pszSrc,   TRUE))  
  goto   bail;  
  }  
   
  /*   Copy   the   datafile   */  
  pszFile   =   ReferenceFileName(pDrvInfo->pDataFile);  
  if   (pszFile)  
  {  
  if   (!DuplicateFile(pszFile,   pszDest,   pszSrc,   TRUE))  
  goto   bail;  
  }  
   
  /*   Copy   the   help   file   */  
  pszFile   =   ReferenceFileName(pDrvInfo->pHelpFile);  
  if   (pszFile)  
  {  
  if   (!DuplicateFile(pszFile,   pszDest,   pszSrc,   TRUE))  
  goto   bail;  
  }  
   
   
  /*   Copy   the   Dependent   files   */  
  /*   The   pDrvInfo->pDependentFiles   is   a   double   NULL   terminated   list   of  
        filenames.   We   creep   down   the   list   as   we   reach   the   end   of   each   filename  
        string   until   we   find   the   end   of   the   list   when   we   hit   the   double    
        terminator.  
    */  
  pszDepFiles   =   pDrvInfo->pDependentFiles;  
  while   (pszDepFiles   &&   *pszDepFiles   !=   0)  
  {  
  pszFile   =   ReferenceFileName(pszDepFiles);  
  if   (pszFile)  
  {  
  if   (!DuplicateFile(pszFile,   pszDest,   pszSrc,   TRUE))  
  goto   bail;  
  }  
   
  /*   go   to   next   file   in   the   list   */  
  pszDepFiles   +=   lstrlen(pszDepFiles)+1;  
  }  
   
  return   TRUE;  
   
  bail:  
  return   FALSE;  
  }  
   
  Top

4 楼taianmonkey()回复于 2003-08-02 14:28:10 得分 0

 
  /*  
  Function:   IsDriverInstalled  
   
  Parameters:  
  IN pDriverName -   the   name   of   the   driver   installation.  
   
  Returns:   TRUE   if   we   find   this   driver   installation   by   name   on   this   machine.  
   
  Remarks:  
  Checks   for   a   package   of   driver   fils   installed   by   the   name   of    
  pDriverName.  
   
  If   the   function   has   trouble   looking   for   installed   printer   drivers,   it  
  fails   and   returns   FALSE.  
   
    */  
  BOOL   IsDriverInstalled(const   char   *pDriverName)  
  {  
  DRIVER_INFO_1 *pDI   =   NULL;  
  char *pEnv   =   NULL; //   We'll   never   use   this   on   9x   -   must   always   be   NULL  
  DWORD cbNeeded;  
  DWORD cReturned;  
  BOOL fFound   =   FALSE;  
  DWORD i=0;  
   
   
  //   We   expect   the   following   call   to   fail   so   it   can   tell   us    
  //   how   big   the   buffer   should   be.  
  EnumPrinterDrivers(NULL,   pEnv,   1,   (LPBYTE)NULL,   0,   &cbNeeded,   &cReturned);  
   
  //   we   know   how   big   now,   proceed  
  pDI   =   (DRIVER_INFO_1   *)new   char[cbNeeded];  
  if   (!EnumPrinterDrivers(NULL,   pEnv,   1,   (LPBYTE)pDI,   cbNeeded,   &cbNeeded,   &cReturned))  
  {  
  //   This   is   bad.  
  goto   bail;  
  }  
   
  /*   Now   we   have   the   goods,   look   for   the   driver   installation.  
        If   we   find   it,   return   TRUE.  
        If   we   do   not   find   it,   we   have   already   assumed   it   is   not   installed.  
    */  
  for   (i=0;   i   <   cReturned   &&   !fFound;   i++)  
  {  
  if   (lstrcmpi(pDI[i].pName,   pDriverName)   ==   0)  
  fFound   =   TRUE;  
  }  
   
  delete   ((char   *)   pDI); //   delete   by   the   same   datatype   as   allocated  
  return   fFound;  
   
  bail:  
  delete   ((char   *)   pDI); //   delete   by   the   same   datatype   as   allocated  
  return   FALSE;  
  }  
   
  /*  
  Function:   InstallDriver  
   
  Parameters:  
  IN pPrinterUNC -   the   UNC   path   to   the   printer   share   on   a   Windows   NT   or   2000  
   
  Remarks:  
  Call   this   function   with   a   string   that   is   a   UNC   path   to   the   printer  
  share.   Example:   "\\spos\flamingo.pcl"  
  The   shared   printer   must   have   the   appropriate   Windows   95/98/98SE   or  
  Millenium   drivers   installed   via   the   sharing   dialog's   Additional   Drivers  
  feature.   This   is   otherwise   known   as   Point   and   Print   in   a   mixed   Windows  
  NT/2000   and   Windows   9x   network.  
   
  As   written,   this   code   takes   the   tactic   that   it   is   desireable   to  
  overwrite   any   existing   driver   files   of   the   same   name.   If   it   cannot   for  
  some   reason,   it   choses   not   to   do   a   partial   install   and   fails.   If   the  
  driver   files   by   "driver   name"   are   already   installed,   it   fails.  
   
  Visual   Basic   declaration:  
   
  Declare   Function   InstallDriver   Lib   "drvsrv.dll"   (   _  
  ByVal   szPrintUNC   As   String   _  
  )   As   Boolean  
   
    */  
  DRVSRV_API   BOOL   WINAPI   InstallDriver(const   char   *pPrinterUNC)  
  {  
  char *pEnv   =   NULL;  
  char szServedPrinter[MAX_PATH];  
  char szSource[MAX_PATH];  
  char szDestination[MAX_PATH];  
  DWORD cbNeeded;  
  DRIVER_INFO_3 *pDI3   =   NULL;  
   
  /*   We   are   going   to   work   on   the   string   so   it   is   good   form   to  
        make   a   copy   of   our   IN   parameter.  
    */  
   
  lstrcpy(szServedPrinter,   pPrinterUNC);  
   
  StripQuotes(szServedPrinter);  
   
   
  //   Get   information   for   the   printer   drivers   that   are   served.  
  if   (!GetDriverInfo(szServedPrinter,   &pDI3))  
  {  
  //   Either   the   UNC   path   for   the   printer   share   inpServerPrinter  
  //   is   bogus,   or   something   much   more   sinister   has   occured.  
  return   FALSE;  
  }  
   
  //   Check   for   existing   driver  
  if   (IsDriverInstalled(pDI3->pName))  
  {  
  //   Already   installed,   don't   bother   to   update  
  delete   ((char   *)   pDI3); //   delete   by   the   same   datatype   as   allocated  
  return   FALSE;  
  }  
   
   
  //   Copy   the   driver   files   to   the   place   indicated   by   Windows  
  if   (!GetPrinterDriverDirectory(NULL,   pEnv,   1,   (LPBYTE)szDestination,   sizeof(szDestination),   &cbNeeded)   ||  
  !GetDriverServerPath9x(szServedPrinter,   szSource,   sizeof(szSource)))  
  {  
  delete   ((char   *)   pDI3); //   delete   by   the   same   datatype   as   allocated  
  return   FALSE;  
  }  
   
  /*   Now   that   we   have   what   to   copy,   from   where   to   get   them,   and   where   to   put  
        them,   do   the   copy.  
    */  
  if   (!CopyDriverFiles(pDI3,   szDestination,   szSource))  
  {  
  delete   ((char   *)   pDI3); //   delete   by   the   same   datatype   as   allocated  
  return   FALSE;  
  }  
   
  /*   Tweak   Driver   Information   as   necessary  
        We   change   cVersion   because   it   is   typically   zero   when   it   comes   from    
        NT   but   it   is   arbitrarily   and   typically   1K   on   Windows   9x.  
   
        Note   that   this   is   not   the   release   version   of   the   driver   files   that   one  
        finds   in   the   file   properties   dialog.  
  */  
  pDI3->cVersion   =   1024;  
   
  //   Install   the   Driver   files  
  if   (!AddPrinterDriver(NULL,   3,   (LPBYTE)pDI3))  
  {  
  delete   ((char   *)   pDI3); //   delete   by   the   same   datatype   as   allocated  
  return   FALSE;  
  }  
   
  //   Done  
  delete   (char*)   pDI3;  
   
  return   TRUE;  
   
  }  
  Top

5 楼chinahu3000()回复于 2003-08-04 09:45:20 得分 0

老大,好像不行,那个GetDriverInfo是可以,但是我是要去安装,以前没有那个Driver的,而且不同的Drive   ::pDI3   =   (DRIVER_INFO_3   *)new   char[cbNeeded];cbNeeded  
    不一的,我总是没法用AddPrinterDriverTop

6 楼chinahu3000()回复于 2003-08-05 13:04:34 得分 0

upTop

7 楼chinahu3000()回复于 2003-08-06 08:35:17 得分 0

upTop

相关问题

  • 那个老大有API的常数介绍。中文的。
  • 那位老大用过东软的短信网关api(java版的),解决了问题分数大大的给!
  • 那位老大给弄个BCB下用API实现的串口通信例子?先谢了!
  • 各位老大:
  • duckcn!!!!!!!!!老大!!!!!
  • 各位老大!
  • 叶老大请进!
  • 老大们,帮忙
  • 叶老大进来...
  • 16大的老大

关键词

  • rundll32
  • exported
  • include
  • functions

得分解答快速导航

  • 帖主:chinahu3000

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo