SuppressUnmanagedCodeSecurity

Hello,

could anyone help me ? I need to create a window as a form in Visual COBOL .NET and then create a listview object into this form but from the listview class written in simple native code. So after creation of the form I need to call native code with the handle of the form and here's the problem. First time I use the form handle in the native code as a parameter in calling Windows API functions causes exception and the process is terminated. I was looking for the solution and I've found that perhaps something like SuppressUnmanagedCodeSecurity attribute must be specified in the calling managed code. But I don't know if I'm right and if I'm how to declare it. In the attachment file is dialog-box with the exception thrown by first calling Windows API with the form handle.

  • I am not really sure what is causing the exception as there really isn't enough detail.

    How are you passing the Form's handle to native code and what is the Windows API call where it is being used?

    I believe that this should work if you get the handle using:

       declare myhandle as type IntPtr = self::Handle

    and pass the IntPtr into native code

    but I have never tried this.

    Attributes can be assigned in managed code at the class level or at the method level, etc.

          class-id winformhandle.Form1 is partial

          inherits type System.Windows.Forms.Form

          attribute System.Security.SuppressUnmanagedCodeSecurity.

  • Thanks for your reply.

    I wrote it exactly the same way you told me to do:

    (1) I obtain the handle the same way that you mentioned. I'm only not sure how to pass the handle correctly to the native code, so in managed code I added these lines in addition

    01  l-Int32                     type System.Int32.

    set l-Int32 to l-hwnd::ToInt32

    and in the native code I declared this parameter in linkage section as 01  ln-hwnd pic x(4) comp-5. Maybe it's not neccesary, I don't know.

    (2) I added the attribute to my class the same way that you mentioned. I didn't noticed that method could have attribute - maybe this way ?

    method-id CreateListview final private

                                                  attribute System.Security.SuppressUnmanagedCodeSecurity.

    (3) And finally the Windows API, where it's being used... at first I just wanted to create a "NetExpress object" by calling

    invoke Window "fromHandle" using ln-hwnd

                                                   returning aWindow

    where Window is just class "window" declared in class-control and aWindow an item declared as object reference. And then I just wrote some "test" invoke

    invoke aWindow "GetTitle" returning aTitle

    to check the handle parameter was passed ok. But just this invoke caused the exception and looking inside the NetExpress library into the code processed by this invoke I found out that this exception appears by calling

       call WAPI GetWindowTextLength using by value ln-hwnd

                                                             returning lsSize

    After that I tested one more API call

       call WAPI GetWindowRect using by value ln-hwnd

                                                                   by reference lsRect

                                                 returning lsBool

    to be sure that the result is the same and that the exception is caused generally by Windows API calling. So this is my experience. Maybe the mistake is some bad type of compilation or so, maybe the code is wrong. I don't know.

    Thank you.

  • Thanks for your reply.

    I wrote it exactly the same way you told me to do:

    (1) I obtain the handle the same way that you mentioned. I'm only not sure how to pass the handle correctly to the native code, so in managed code I added these lines in addition

    01  l-Int32                     type System.Int32.

    set l-Int32 to l-hwnd::ToInt32

    and in the native code I declared this parameter in linkage section as 01  ln-hwnd pic x(4) comp-5. Maybe it's not neccesary, I don't know.

    (2) I added the attribute to my class the same way that you mentioned. I didn't noticed that method could have attribute - maybe this way ?

    method-id CreateListview final private

                                                  attribute System.Security.SuppressUnmanagedCodeSecurity.

    (3) And finally the Windows API, where it's being used... at first I just wanted to create a "NetExpress object" by calling

    invoke Window "fromHandle" using ln-hwnd

                                                   returning aWindow

    where Window is just class "window" declared in class-control and aWindow an item declared as object reference. And then I just wrote some "test" invoke

    invoke aWindow "GetTitle" returning aTitle

    to check the handle parameter was passed ok. But just this invoke caused the exception and looking inside the NetExpress library into the code processed by this invoke I found out that this exception appears by calling

       call WAPI GetWindowTextLength using by value ln-hwnd

                                                             returning lsSize

    After that I tested one more API call

       call WAPI GetWindowRect using by value ln-hwnd

                                                                   by reference lsRect

                                                 returning lsBool

    to be sure that the result is the same and that the exception is caused generally by Windows API calling. So this is my experience. Maybe the mistake is some bad type of compilation or so, maybe the code is wrong. I don't know.

    Thank you.

  • Thanks for your reply.

    I wrote it exactly the same way you told me to do:

    (1) I obtain the handle the same way that you mentioned. I'm only not sure how to pass the handle correctly to the native code, so in managed code I added these lines in addition

    01  l-Int32                     type System.Int32.

    set l-Int32 to l-hwnd::ToInt32

    and in the native code I declared this parameter in linkage section as 01  ln-hwnd pic x(4) comp-5. Maybe it's not neccesary, I don't know.

    (2) I added the attribute to my class the same way that you mentioned. I didn't noticed that method could have attribute - maybe this way ?

    method-id CreateListview final private

                                                  attribute System.Security.SuppressUnmanagedCodeSecurity.

    (3) And finally the Windows API, where it's being used... at first I just wanted to create a "NetExpress object" by calling

    invoke Window "fromHandle" using ln-hwnd

                                                   returning aWindow

    where Window is just class "window" declared in class-control and aWindow an item declared as object reference. And then I just wrote some "test" invoke

    invoke aWindow "GetTitle" returning aTitle

    to check the handle parameter was passed ok. But just this invoke caused the exception and looking inside the NetExpress library into the code processed by this invoke I found out that this exception appears by calling

       call WAPI GetWindowTextLength using by value ln-hwnd

                                                             returning lsSize

    After that I tested one more API call

       call WAPI GetWindowRect using by value ln-hwnd

                                                                   by reference lsRect

                                                 returning lsBool

    to be sure that the result is the same and that the exception is caused generally by Windows API calling. So this is my experience. Maybe the mistake is some bad type of compilation or so, maybe the code is wrong. I don't know.

    Thank you.

  • I can get this to work correctly but it seems like the run-time is forcing parameters being passed directly as integers to be passed by value even when by value isn't specified.

    If I do not use by value in the procedure division header of the native subprogram than I get the same exception error as you.

    I am still researching this but could you give this a try?

  • Actually if you compile the managed code application using the directive ILNONATIVE the pass by reference will work correctly.

    Thanks.

  • Verified Answer

    managed app compiled with $set noilnative

             declare myhandle as binary-long = self::Handle as binary-long
             declare myret as binary-long
             call "subprog" using myhandle myret

    native subprog.

          working-storage section.
          01 pp  procedure-pointer.
          linkage section.
          01 winhandle    pic x(4) comp-5.
          01 retlength    pic x(4) comp-5.
          procedure division using winhandle retlength.
              set pp to entry "User32"
              call winapi "GetWindowTextLengthA"
                 using by value winhandle
                 returning retlength

  • Chris,

    Pardon, but I believe it is spelled like this:  NOILNATIVE

    Thanks

  • Yes, you are correct the NO is before the IL. I spelled it correctly in the second post with the example.

  • Superb. When added the "by value" declaration to the procedure division header in the native subprogram, it works correctly. After that I tried to remove the attribute System.Security.SuppressUnmanagedCodeSecurity and it still seems ok. Do you think that this attribute should be still used ? Thanky you very much.

    Now I'll try the directive NOILNATIVE.