home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winnt / netapi / netshare / netshare.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-11  |  6.0 KB  |  238 lines

  1. /*++
  2.  
  3. Copyright (c) 1995, 1996  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     netshare.c
  8.  
  9. Abstract:
  10.  
  11.     This module illustrates how to use the Windows NT Lan Manager API
  12.     in conjunction with the Win32 security API to create a new share
  13.     on an arbitrary machine with permissions that grant an arbitrary
  14.     user/group Full Access to the share.
  15.  
  16. Author:
  17.  
  18.     Scott Field (sfield)    01-Oct-95
  19.  
  20. --*/
  21.  
  22. #include <windows.h>
  23. #include <lm.h>
  24. #include <stdio.h>
  25.  
  26. #define RTN_OK 0
  27. #define RTN_USAGE 1
  28. #define RTN_ERROR 13
  29.  
  30. //
  31. // Note: UNICODE entry point and argv.  This way, we don't need to bother
  32. // with converting commandline args to Unicode
  33. //
  34.  
  35. int
  36. __cdecl
  37. wmain(
  38.     int argc,
  39.     wchar_t *argv[]
  40.     )
  41. {
  42.     LPWSTR DirectoryToShare;
  43.     LPWSTR Sharename;
  44.     LPWSTR Username;
  45.     LPWSTR Server;
  46.  
  47.     PSID pSid = NULL;
  48.     DWORD cbSid;
  49.  
  50.     WCHAR RefDomain[DNLEN + 1];
  51.     DWORD cchDomain = DNLEN + 1;
  52.     SID_NAME_USE peUse;
  53.  
  54.     SECURITY_DESCRIPTOR sd;
  55.     PACL pDacl = NULL;
  56.     DWORD dwAclSize;
  57.  
  58.     SHARE_INFO_502 si502;
  59.     NET_API_STATUS nas;
  60.  
  61.     BOOL bSuccess = FALSE; // assume this function fails
  62.  
  63.     if(argc < 4) {
  64.         printf("Usage: %ls <directory> <sharename> <user/group> [\\\\Server]\n", argv[0]);
  65.         printf(" directory is fullpath of directory to share\n");
  66.         printf(" sharename is name of share on server\n");
  67.         printf(" user/group is an WinNT user/groupname (REDMOND\\sfield, Administrators, etc)\n");
  68.         printf(" optional Server is the name of the computer to create the share on\n");
  69.         printf("\nExample: %ls c:\\public public Everyone\n", argv[0]);
  70.         printf("c:\\public shared as public granting Everyone full access\n");
  71.         printf("\nExample: %ls c:\\private cool$ REDMOND\\sfield \\\\WINBASE\n", argv[0]);
  72.         printf("c:\\private on \\\\WINBASE shared as cool$ (hidden) granting REDMOND\\sfield access\n");
  73.  
  74.         return RTN_USAGE;
  75.     }
  76.  
  77.     //
  78.     // since the commandline was Unicode, just provide pointers to
  79.     // the relevant items
  80.     //
  81.  
  82.     DirectoryToShare = argv[1];
  83.     Sharename = argv[2];
  84.     Username = argv[3];
  85.  
  86.     if( argc > 4 ) {
  87.         Server = argv[4];
  88.     } else {
  89.         Server = NULL; // local machine
  90.     }
  91.  
  92.     //
  93.     // initial allocation attempt for Sid
  94.     //
  95. #define SID_SIZE 96
  96.     cbSid = SID_SIZE;
  97.  
  98.     pSid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
  99.     if(pSid == NULL) {
  100.         printf("HeapAlloc error!\n");
  101.         return RTN_ERROR;
  102.     }
  103.  
  104.     //
  105.     // get the Sid associated with the supplied user/group name
  106.     // force Unicode API since we always pass Unicode string
  107.     //
  108.  
  109.     if(!LookupAccountNameW(
  110.         NULL,       // default lookup logic
  111.         Username,   // user/group of interest from commandline
  112.         pSid,       // Sid buffer
  113.         &cbSid,     // size of Sid
  114.         RefDomain,  // Domain account found on (unused)
  115.         &cchDomain, // size of domain in chars
  116.         &peUse
  117.         )) {
  118.  
  119.         //
  120.         // if the buffer wasn't large enough, try again
  121.         //
  122.  
  123.         if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  124.  
  125.             pSid = (PSID)HeapReAlloc(GetProcessHeap(), 0, pSid, cbSid);
  126.  
  127.             if(pSid == NULL) {
  128.                 printf("HeapReAlloc error!\n");
  129.                 goto cleanup;
  130.             }
  131.  
  132.             cchDomain = DNLEN + 1;
  133.  
  134.             if(!LookupAccountNameW(
  135.                 NULL,       // default lookup logic
  136.                 Username,   // user/group of interest from commandline
  137.                 pSid,       // Sid buffer
  138.                 &cbSid,     // size of Sid
  139.                 RefDomain,  // Domain account found on (unused)
  140.                 &cchDomain, // size of domain in chars
  141.                 &peUse
  142.                 )) {
  143.                     printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
  144.                     goto cleanup;
  145.                 }
  146.  
  147.         } else {
  148.             printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
  149.             goto cleanup;
  150.         }
  151.     }
  152.  
  153.     //
  154.     // compute size of new acl
  155.     //
  156.  
  157.     dwAclSize = sizeof(ACL) +
  158.         1 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
  159.         GetLengthSid(pSid) ;
  160.  
  161.     //
  162.     // allocate storage for Acl
  163.     //
  164.  
  165.     pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
  166.     if(pDacl == NULL) goto cleanup;
  167.  
  168.     if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
  169.         goto cleanup;
  170.  
  171.     //
  172.     // grant GENERIC_ALL (Full Control) access
  173.     //
  174.  
  175.     if(!AddAccessAllowedAce(
  176.         pDacl,
  177.         ACL_REVISION,
  178.         GENERIC_ALL,
  179.         pSid
  180.         )) goto cleanup;
  181.  
  182.     if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
  183.         goto cleanup;
  184.  
  185.     if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) {
  186.         fprintf(stderr, "SetSecurityDescriptorDacl error! (rc=%lu)\n",
  187.             GetLastError());
  188.         goto cleanup;
  189.     }
  190.  
  191.     //
  192.     // setup share info structure
  193.     //
  194.  
  195.     si502.shi502_netname = (LPTSTR) Sharename;
  196.     si502.shi502_type = STYPE_DISKTREE;
  197.     si502.shi502_remark = NULL;
  198.     si502.shi502_permissions = 0;
  199.     si502.shi502_max_uses = SHI_USES_UNLIMITED;
  200.     si502.shi502_current_uses = 0;
  201.     si502.shi502_path = (LPTSTR) DirectoryToShare;
  202.     si502.shi502_passwd = NULL;
  203.     si502.shi502_reserved = 0;
  204.     si502.shi502_security_descriptor = &sd;
  205.  
  206.     nas = NetShareAdd(
  207.         (LPTSTR) Server,         // share is on local machine
  208.         502,            // info-level
  209.         (LPBYTE)&si502, // info-buffer
  210.         NULL            // don't bother with parm
  211.         );
  212.  
  213.     if(nas != NO_ERROR) {
  214.         printf("NetShareAdd error! (rc=%lu)\n", nas);
  215.         goto cleanup;
  216.     }
  217.  
  218.     bSuccess = TRUE; // indicate success
  219.  
  220. cleanup:
  221.  
  222.     //
  223.     // free allocated resources
  224.     //
  225.     if(pDacl != NULL)
  226.         HeapFree(GetProcessHeap(), 0, pDacl);
  227.  
  228.     if(pSid != NULL)
  229.         HeapFree(GetProcessHeap(), 0, pSid);
  230.  
  231.     if(!bSuccess) {
  232.         return RTN_ERROR;
  233.     }
  234.  
  235.     return RTN_OK;
  236. }
  237.  
  238.