|
I've posted our code below. Does anyone see anything obvious we might be doing wrong ?
Yes, very obvious. You're passing a pointer instead of a character field for the password!!
Here's your prototype:
D GetProfile Pr ExtPgm('QSYGETPH') D UserID 10A D Password * D Handle 12A D ErrorCode 256A Options(*Varsize : *NoPass) D PswLength 10I 0 Options(*NoPass) D CCSIDCode 10I 0 Options(*NoPass)
The API documentation states that the 2nd parameter is a CHAR field, not a pointer. Instead of passing a string containing the password, you're passing a memory address to the API. The API is reading that memory address, and thinking that you're intending that 16-byte hex value (the address) to be the password.
For example, when the subprocedure starts, the program needs memory for the "password" variable (it gets it's own memory, since it's passed by value.) The program asks the operating system for 10 bytes of the memory, and the os says (for example) that it can use 10 bytes starting with memory address x'8000000000000000C655098D43073340'.
It then copies this address to the passwordin variable -- and passes that number, x'8000000000000000C655098D43073340', instead of the actual password, to the API. The API thinks that this number is supposed to be the password -- and tries it, only to find that it's not the right password for the userid.
Change your prototype to look like this:
D GetProfile Pr ExtPgm('QSYGETPH') D UserID 10A const D Password 32767A const options(*varsize) D Handle 12A D ErrorCode 256A Options(*Varsize : *NoPass) D PswLength 10I 0 const Options(*NoPass) D CCSIDCode 10I 0 const Options(*NoPass)
Note that in addition to coding the password as a character field, I also made the input-only fields be "const". This'll make the API easier to call in many situations, it's also more self-documenting.
When you call it, do this: //?Retrieve user Profile; CallP GetProfile( %late(LC:UC:UserID) : password : handle : ERRDS: : %len(password) : 0 );Note that because I used CONST on the prototype, I can do some calculations on the call to the API. This makes the code shorter, eliminates the need for temporary one-use variables, and IMHO it's easier to read, because I mentally look at the call and say "Call with uppercase userid, call with the length of the password field", etc. If you put variables there, I have to go back and examine them to see what you did to them.
I also changed your CCSID from 37 to 0. 37 means that it'll always be EBCDIC for English languages in the USA. If this code is ever run elsewhere, the fact that this is hard-coded might screw someone up. Changing it to 0 tells it to retrieve the job's CCSID value and use that. That's usually a better choice for the default.
But, all of these are just "tips" for improvement. The actual error is the fact that you're passing a pointer instead of a character field for the password.
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.