NT 4.0 Set Workgroup via Win32 API

This was asked/answered before (See http://www.experts-exchange.com/topics/Q.10029737) but the answer is still not working.  

Here is a snippet of my code:

WKSTA_INFO_100 **ppwksta, *pwksta;

ppwksta = &pwksta;

            stat = NetWkstaSetInfo(NULL, 100, (LPBYTE)pwksta, NULL);
            if(stat != NERR_Success){
                  CString errmsg;
                  errmsg.Format(_T("Error in NetWkstaSetInfo() : %s"), ErrorToString(stat));
                  AfxMessageBox(errmsg, MB_OK);
                  ASSERT(FALSE);
            }

The error returned is:

"The system call level is not correct"

The last answer I got about this part of the problem is:

Got the answer...
It is a security issue. Even though you are an admin, you process token does not automatically give you security rights. You need to adjust your token using OpenProcessToken()

"To gain access to a security access control list (SACL), a process must have the SE_SECURITY_NAME privilege. When requesting access, the calling process must request ACCESS_SYSTEM_SECURITY in the desired access mask. "

While I'm not sure that the above approach is the right way to do this, any solution that gets this working will get the points.
LVL 32
jhanceAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jhanceAuthor Commented:
Edited text of question
0
alexoCommented:
How about trying (add error checking):

    LPBYTE bp;
    NetWkstaUserGetInfo(NULL,(DWORD)1,&bp);
    // Change elements in (*bp) that need to be changed...
    NetWkstaSetInfo(NULL, 100, bp, NULL);
    NetApiBufferFree(bp);

0
jhanceAuthor Commented:
alexo,

I don't think this is it.  The function NetWkstaUserGetInfo doesn't return the DOMAIN name.  If you don't read the (poor) documentation on this function you might think that the wkui1_logon_domain member of the WKSTA_USER_INFO_1 structure is the domain name but it is not.  It's the user's logon name on whatever domain server he is currently using.  I want to change the wki100_langroup member of:

typedef struct _WKSTA_INFO_100 {
    DWORD     wki100_platform_id;
    LPWSTR    wki100_computername;
    LPWSTR    wki100_langroup;
    DWORD     wki100_ver_major;
    DWORD     wki100_ver_minor;
}WKSTA_INFO_100, *PWKSTA_INFO_100, *LPWKSTA_INFO_100;

Again, I'm not sure that NetWkstaSetInfo can actually change this but there must be a way of doing it.  Microsoft allows you to change this from th "Change" button on the Network Control Panel under NT.
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

alexoCommented:
Cut&paste error.
I meant NetWkstaGetInfo(), not NetWkstaUserGetInfo().
Does it make more sense now?

0
jhanceAuthor Commented:
No, it doesn't help.  Here is the code that doesn't work:

      // Set the COMPUTERNAME and WORKGROUP to the values specified
      WKSTA_INFO_100 **ppwksta, *pwksta;
      NET_API_STATUS stat;

      ppwksta = &pwksta;

      CString new_wg;
      BYTE *p;

      GetDlgItemText(IDC_LANGROUP, new_wg);
      ASC2UNI(&p, new_wg);
      stat = NetWkstaGetInfo(NULL, 100, (LPBYTE *)ppwksta);
      if(stat != NERR_Success){
            AfxMessageBox(Error2String(stat), MB_OK);
      }
      else{

            stat = NetWkstaSetInfo(NULL, 100, (LPBYTE)pwksta, NULL);
            if(stat != NERR_Success){
                  AfxMessageBox(Error2String(stat), MB_OK);
            }
      }

      delete p;

0
alexoCommented:
Got it!

ERROR.H says:

    #define ERROR_INVALID_LEVEL     124
    /* unimplemented level for info retrieval or setting */

Ergo, NetWkstaSetInfo() doesn't like level 100.

Searching through LMWKSTA.H we get:

    //
    // NetWkstaGetInfo only.  System information - guest access
    //
    typedef struct _WKSTA_INFO_100 {
        DWORD   wki100_platform_id;
        LPTSTR  wki100_computername;
        LPTSTR  wki100_langroup;
        DWORD   wki100_ver_major;
        DWORD   wki100_ver_minor;
    }WKSTA_INFO_100, *PWKSTA_INFO_100, *LPWKSTA_INFO_100;

Yup, level 100 is for getting information only.
Unfortunately, no other level allows you to modify the data present in level 100.

References:
  http://premium.microsoft.com/msdn/library/sdkdoc/c245_7bhy.htm

I suggest looking into the NetBios() function to do what you need (and getting a good netbios reference).
0
alexoCommented:
You can also try researching NetUserModalsSet().  See:
  http://premium.microsoft.com/msdn/library/sdkdoc/pdnds/ntlmapi_7omr.htm
0
jhanceAuthor Commented:
Sorry, you've told me what I already know.  NetWkstaSetInfo doesn't work the way I'm using it.  You may be correct in that it's read only but I have little confidence in the documentation on these functions.  Someone else suggested that it was a privs problem and that by getting the right privs it could be done.  Perhaps this is the answer.  But...back to my ORIGINAL question:

HOW TO: NT 4.0 Set Workgroup via Win32 API

If you want the points, help me figure out how to do this.
0
alexoCommented:
>> Sorry, you've told me what I already know [...]

I just can figure out why the sour tone.  I've told you more than you knew.  I.e.:
(a) NetWkstaSetInfo() cannot be used at all for your purpose.
(b) The error you get is definitely NOT "a privs problem".
(c) You have to use either the NetBios() or the NetUserModalsSet() APIs.
And (d) I pointed you to URLs that can give you more information on this.

At least I saved you the time researching dead ends.

>> If you want the points, help me figure out how to do this.

The points?  I'm doing it because I like sharing knowledge and helping people, not because some virtual "points" that don't mean a thing.

And the funny part is that I was under the impression that I WAS helping you figure out how to do this.
0
jhanceAuthor Commented:
I'm not meaning to have a "sour" tone...but, you answered and locked the question without a real answer.  I have reasonable confidence that this task can be done so your answer of NetWkstaSetInfo can't do the job is not an answer to the question.  As you probably already know, the Windows API NET functions are some of the most poorly documented functions in the whole mess that is Windows.  

You mentioned a good NETBIOS reference.  I've not seen a book that I would call a reference on the subject.  If you can suggest one, that might be a start.  I've researched this quite a bit and all the books I've seen concentrate on making connections to server resources via the NETBIOS functions.  I've never seen a single reference to setting the WORKGROUP name for a client.
0
alexoCommented:
First, an appology: NetUserModalsSet() is a waste of time.  Don't know what got me thinking it can help.

>> 'm not meaning to have a "sour" tone...but, you answered and locked the question without a real answer.  I have reasonable confidence that this task can be done so your answer of NetWkstaSetInfo can't do the job is not an answer to the question.

That depends on your definition of an "answer".  If I asked you how to square the circle and you told me it can't be done would that be an answer?  Oh, whatever, have it your way.  I'll refrain from locking the question until you invite me to.  Fair?

Now about that "reasonable confidence".  The error code you're getting says "The system call level is not correct" (as you mentioned yourself).  That means NetWkstaSetInfo() will now accept level 100.  No way around it.

Enter NetBIOS.  Did you try creating a groupname using the NCBADDGRNAME NetBIOS command?  Do that, verify that the name exists using "NBTSTAT -n" and we'll continue from there.

You should see something like:

   Name               Type         Status
---------------------------------------------
MY_DOMAIN <00>  GROUP       Registered

Some references to help you continue:
  http://premium.microsoft.com/msdn/library/sdkdoc/pdnds/netbios_59ut.htm
  KB articles Q124960 and Q138037.

0
tonpCommented:
Changing the domainname (workgroup) is somewhat complicated. There's a detailed sample program available that shows you how to do this, the key function is LsaSetInformationPolicy. The sample code and additional information can be found in the microsoft knowledbase article Q170620. (search at www.microsoft.com or look it up in MSDN).

Ton

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jhanceAuthor Commented:
tonp,

This KB article look very promising.  I'll work on this today and see if it works out.  Thanks....
0
jhanceAuthor Commented:
tonp,

Thanks for the pointer.  This is _exactly_ what I've been looking for.  

Have you ever seen any documentation of this entire (i.e. LSA) API?  I searched my MSDN disks and the online library but only found a reference to the NTSECAPI.H header file.
0
tonpCommented:
No, I haven't seen this before anywhere, it took me quite a while to discover this.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.