Page 2 of 3 <123>
Topic Options
#158099 - 2006-03-02 05:20 PM Re: ChangeVLKey() - Test Function
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1894
Loc: Hilversum, The Netherlands
Richard: I think I've caught everything safely in my last modification in the first post.

Benny: Then it is because of the Retail version I'm afraid

Top
#158100 - 2006-03-02 09:19 PM Re: ChangeVLKey() - Test Function
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
Well I think if it's going to be a UDF it should be modified a little bit.

As for free tools out there to do this, take a look at RockXP
http://www.rockxp.org/

Download here:
http://korben.othersystem.net/web/softs/RockXP3.exe

Recommended UDF changes

Function ChangeVLKey($VOL_PROD_KEY)
Dim $obj, $objects
;Key is without hyphens (ABCDEFGHIJKLMNOPQRSTUVWXY)
$objects = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("win32_WindowsProductActivation")
If @ERROR
;ChangeVLKey should not have a value if we got an error
$ChangeVLKey = 0
;Convert the error to readable format
Exit Val('&' + Right(DecToHex(@ERROR), 4))
EndIf
For Each $obj in $objects
$ChangeVLKey = $obj.SetProductKey($VOL_PROD_KEY)
Next
;Assumes we got here okay so exit with no error
Exit 0
EndFunction

 

Top
#158101 - 2006-03-03 08:44 AM Re: ChangeVLKey() - Test Function
Arend_ Moderator Offline
MM club member
*****

Registered: 2005-01-17
Posts: 1894
Loc: Hilversum, The Netherlands
I'll have a look trough this, the use of DecToHex might prove usefull.

Also if you want a good tool that changes any xp license key use this: KeyFinder 1.5b3
Or goto the site for more info: http://www.magicaljellybean.com

Top
#158102 - 2006-03-03 06:57 PM Re: ChangeVLKey() - Test Function
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
Yep, I've tried both those before. Just like the RockXP a bit better myself. Thanks for the links though.
Top
#158103 - 2006-03-05 02:05 PM Re: ChangeVLKey() - Test Function
Sealeopard Offline
KiX Master
*****

Registered: 2001-04-25
Posts: 11164
Loc: Boston, MA, USA
Soory to jump in so late. IMHO, the function should return the error code only in EXIT @ERROR and the $ChangeVLKey whatever the SET/GETOBJCT generates (0 in case of success otherwise WMI error code, thus
Code:

Function ChangeVLKey($VOL_PROD_KEY)
Dim $obj, $objects
;Key is without hyphens (ABCDEFGHIJKLMNOPQRSTUVWXY)
$objects = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("win32_WindowsProductActivation")
If @ERROR
;ChangeVLKey should not have a value if we got an error
$ChangeVLKey = Val('&' + Right(DecToHex(@ERROR), 4))
;Convert the error to readable format
Exit Val('&' + Right(DecToHex(@ERROR), 4))
EndIf
For Each $obj in $objects
$ChangeVLKey = $obj.SetProductKey($VOL_PROD_KEY)
Next
;Assumes we got here okay so exit with no error
Exit @ERROR
EndFunction

_________________________
There are two types of vessels, submarines and targets.

Top
#158104 - 2006-03-06 05:40 AM Re: ChangeVLKey() - Test Function
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
I don't agree. If there is ANY error your code will be have invalid / unpredictable results and should quit the UDF then and there not set the UDF value to it.
Top
#158105 - 2006-03-06 06:28 AM Re: ChangeVLKey() - Test Function
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
I can agree that the last Exit @ERROR is probably better

However I don't think setting the Function to the Error is good.

As an example let's suppose that you had a function that read a remote value
from the registry and you expected it to be between 1 and 5
Well as you would rewrite it unless one specifically tested for the Error condition first
(I agree that is probably best coding but we all know that we don't all always do that first)

Example:

Dim $T
$T = ReadRegValue('some computer')
'The value was: ' + $T ?



In this example if say 5 came back the admin would think, cool that's the right value and
proceed from there, but in reality it could easily have been 5 - Access Denied

Setting the Function to 0 after ANY error prohibits any misunderstanding like that.
With the way it is now it would come back blank

If one did better coding one would know, but I still don't see the value in setting it to the error.

Dim $T
$T = ReadRegValue('some computer')
If @ERROR
  'ERROR: There was an error accessing the information: ' + @ERROR + ' - ' + @SERROR ?
Else
  'The value was: ' + $T ?
EndIf

Top
#158106 - 2006-03-06 07:28 AM Re: ChangeVLKey() - Test Function
NTDOC Administrator Offline
Administrator
*****

Registered: 2000-07-28
Posts: 11623
Loc: CA
After thinking about it some more, I think setting the value to blank if an error was detected is better than setting it to 0

$ChangeVLKey = 0
Would be better set to
$ChangeVLKey = ""

I'm open to further discussion on this subject as well as WHY you think it should be one way or another.

Top
#158107 - 2006-03-06 10:37 AM Re: ChangeVLKey() - Test Function
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
A function should always explicitly return a value, even if it is a null value.

When the purpose of a function is to return data then it is reasonable to return either the data on success or a null value on an error - I agree that in this case that returning an error value is unwise.

However, when the function is not expected to return data then it makes sense use the error status as the return value.

Apart from anything else this makes it consistent with the KiXtart built-in functions (e.g. Open() EnumValue()) which use the error state as their exit value.

The code that I posted earlier (repeated here for clarity) does just that:
Code:
Function ChangeVLKey($VOL_PROD_KEY)
Dim $obj, $objects, $result
;Key is without hyphens (ABCDEFGHIJKLMNOPQRSTUVWXY)

$objects = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("win32_WindowsProductActivation")

If Not @ERROR
For Each $obj in $objects
$result = $obj.SetProductKey($VOL_PROD_KEY)
Next
EndIf
$ChangeVLKey = @error
Exit $ChangeVLKey
EndFunction


Top
#158108 - 2006-03-06 01:50 PM Re: ChangeVLKey() - Test Function
Sealeopard Offline
KiX Master
*****

Registered: 2001-04-25
Posts: 11164
Loc: Boston, MA, USA
The problem is that the WMI action will return '0' to indicate success, thus if someone checks for the UDF return but not the @ERROR, it'll evaluate to 'success' even though the action failed.
_________________________
There are two types of vessels, submarines and targets.

Top
#158109 - 2006-03-06 02:08 PM Re: ChangeVLKey() - Test Function
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Quote:

The problem is that the WMI action will return '0' to indicate success, thus if someone checks for the UDF return but not the @ERROR, it'll evaluate to 'success' even though the action failed




Eh? What do you mean?

Both the exit value and the function value are set to @ERROR wether the error is set by the initial creation of the object or the enumeration.

Top
#158110 - 2006-03-06 02:15 PM Re: ChangeVLKey() - Test Function
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Richard,

I think that those examples are special cases that return EXTENDED information, and return 0 on success, the opposite of what this and many other functions do.

As for the rest of the comments...

If you expect a function to return non-zero data, it should return zero or null in the case of an error, and exit with the error value. This allows
Code:

If Func()
; got a reply - don't care, just do!
Else
; No reply - there's a problem, check @ERROR
EndIf


- or -
Code:

$X = Func()
If $X
; got a reply - OK to process the data
Else
; No reply - there's a problem, check @ERROR
EndIf



Conversely, if a function normally does not return specific data, it is helpful to return status info (which may or may not be the ERROR code). Look at the ExistKey/KeyExist functions. These return Status, one inverted, the other "fixed" to return true. The original one returned "success", which wasn't too helpful when doing simple "If ExistKey()" tests. The newer function returns status, not error info.

Think about your Open example.. the sample in the book looks something like
Code:

If Open(1, 'Filename', 2) = 0


Which is generally what I see in UDFs that use it. However, consider
Code:

$RC = -3
$Ct = 0
While $RC = -3 And $Ct < 10
$RC = Open(1, 'Filename', 2) = 0
$Ct = $Ct + 1
If $RC = -3 Sleep .5 EndIf
Loop


This allows code to be more robust in an environment where many copies of a script may need to access a file. This is a simplified example, but should illustrate the point of checking the status returned.

In this UDF example, and the one Doc is referring to, the UDF returns a specific value - valid data. Even worse, the UDFs return strings of numbers (Strings, because they may have dashes). Returning a pure number as an error is counter-intuitive. It should return a null (empty string) if it usully returns strings, and a zero if it usually returns numbers. If returning zero as a numeric value is valid, then the calling code should ALWAYS check the ERROR macro.

Mode A - Either I get data (non-zero, non-null) or I don't, and if I don't, I check the ERROR macro for more info.

Mode B - I don't expect data, so if I get some, it's a problem and should check the value further, and possibly the @ERROR macro.

One last example.. Consider a UDF that updates some data repository (file, database, registry). It normally returns nothing, indicating success. It performs a "complex" validation process before writing the data, and if it fails validation, it exits with error 87.

Hmm, bad data. What kind of bad data?
The value returned might have the following meanings:
0 = Success
-1 = Out of Bounds - Low
1 = Out of Bounds - High
2 = Incorrect data type (not number)
3 = Null value supplied
4 = System Error

Of course, a return of 4 would indicate that some other error occurred, and would be identified by the exit value in the ERROR macro.

Bottom line, I'm definitly against arbitrarily returning ERROR values as data unless the conditions warrant as outlined above.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#158111 - 2006-03-06 02:22 PM Re: ChangeVLKey() - Test Function
Shawn Administrator Offline
Administrator
*****

Registered: 1999-08-13
Posts: 8611
Since this UDF can theoretically change multiple instances of a class (its looping through a collection) - if I was coding this UDF - I would probably create it so that it returned the number of instances changed (which may be usefull information) and if an error occurred it would return 0 (zero nothing changed) and then @ERROR would indicate the error.
Top
#158112 - 2006-03-06 02:39 PM Re: ChangeVLKey() - Test Function
Shawn Administrator Offline
Administrator
*****

Registered: 1999-08-13
Posts: 8611
eh, strike that idea - this is one of those "WMI returns a collection but it will always be only one item" thingies.
Top
#158113 - 2006-03-06 03:12 PM Re: ChangeVLKey() - Test Function
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Quote:

I think that those examples are special cases that return EXTENDED information, and return 0 on success, the opposite of what this and many other functions do.




The example script I gave above returns 0 on success or the error which caused the failure. This is consistent with...

AddKey(), AddPrinterConnection(), AddProgramGroup(), AddProgramItem(), BackupEventLog(), DelKey(), LoadHive(), LogEvent(), SendKeys(), SendMessage(), SetConsole(), ShutDown(), WriteProfileString()

... and others.

Maybe I misunderstand. Wouldn't be the first time

Top
#158114 - 2006-03-06 03:20 PM Re: ChangeVLKey() - Test Function
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Ahh I think I see where the confusion lies:
Quote:

In this UDF example, and the one Doc is referring to, the UDF returns a specific value - valid data.




This is not correct. Well, not what you mean anyway

The value of SetProductKey is not a datum as such - it is the same error code that @ERROR is set to:
Quote:

SetProductKey Method of the Win32_WindowsProductActivation Class
The SetProductKey WMI class method updates the system product key for a computer.

This topic uses Managed Object Format (MOF) syntax. For information on using this method see Calling a Method.

uint32 SetProductKey(
string ProductKey
);

Parameters
ProductKey
[in] Unique product key that is licensed for use on the computer. Product keys are alphanumeric strings of 25 characters formatted as follows: xxxxx-xxxxx-xxxxx-xxxxx-xxxxx. The product key must be valid for the media type. Media types include retail, volume-licensing, and OEM.
Return Values
If the method succeeds and the product key is valid, the method returns 0 (zero) and the corresponding product key is updated. Otherwise, the method returns one of the WMI error constants.




Top
#158115 - 2006-03-06 03:25 PM Re: ChangeVLKey() - Test Function
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
The issue is not whether the UDF or Function returns error info as much as being consistent. Those functions you reference do not return Data OR the result (status) codes, they ONLY return the result codes. It makes sense for them to return 0 for success and some status on failure.

Imagine the difficulty if ReadProfileString() returned an error code instead of the data it read! How could you tell, unless you ALWAYS checked the ERROR macro.

I was trying to point out that if a function is expected to return data.. maybe "Variable Data" describes it better, that No Data is a better indication of an error (and a reason to check the ERROR macro) than Error Data, which makes you figure out if what you got was Valid Data or Error Data.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#158116 - 2006-03-06 03:43 PM Re: ChangeVLKey() - Test Function
Richard H. Administrator Offline
Administrator
*****

Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
Quote:

I was trying to point out that if a function is expected to return data.. maybe "Variable Data" describes it better, that No Data is a better indication of an error (and a reason to check the ERROR macro) than Error Data, which makes you figure out if what you got was Valid Data or Error Data.




Yes, that is exactly what I said in my earlier post. I know it's bad form to quote yourself but:
Quote:

Richy says...
When the purpose of a function is to return data then it is reasonable to return either the data on success or a null value on an error - I agree that in this case that returning an error value is unwise.




However, this function never returns any data. It only ever returns an error state.

Top
#158117 - 2006-03-06 03:51 PM Re: ChangeVLKey() - Test Function
Shawn Administrator Offline
Administrator
*****

Registered: 1999-08-13
Posts: 8611
I agree with Richard. So what were agreeing to is that the UDF should remain as is (returning the errorlevel).
Top
#158118 - 2006-03-06 04:08 PM Re: ChangeVLKey() - Test Function
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4396
Loc: New Jersey
Quote:

However, this function never returns any data. It only ever returns an error state.




OK - this situation it makes sense.. I guess I didn't understand the function itself, but had recently had issues with other UDFs that returned data when it worked and returned errors when it didn't, and it made it more complex to code around that.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
Page 2 of 3 <123>


Moderator:  Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
1 registered (Allen) and 466 anonymous users online.
Newest Members
gespanntleuchten, DaveatAdvanced, Paulo_Alves, UsTaaa, xxJJxx
17864 Registered Users

Generated in 0.042 seconds in which 0.014 seconds were spent on a total of 13 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org