locked
Winsock differences in store apps

    Question

  • Hi,

    We have a lot of legacy Winsock code that we can now use (without having to rewrite) in our store app which is obviously fantastic news, however we have found a difference that means that we may still need to rewrite the code which at this point will add considerable work.

    The legacy code uses closed socket handles relying on a suitable error being returned, 10038 in a desktop environment.  However this leads to a "0xC0000008: An invalid handle was specified" exception in the store app.  

    Will this be fixed? Perhaps I can register a app-level exception handler?

    Thanks for the help.

    Monday, January 19, 2015 9:32 AM

All replies

  • Sample code to reproduce the issue:

        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);

        SOCKET thesocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        closesocket(thesocket);

        u_long s = 0;
        int err = ioctlsocket(thesocket, FIONREAD, &s);

    In desktop WSAGetLastError returns 10038 whereas the ioctlsocket throws an exception in a store app.

    Monday, January 19, 2015 11:18 AM
  • Hi Wantabeguitarboy,

    As I can see from the documentation: Windows Sockets Error Codes, 10038 means Socket operation on nonsocket. It's reasonable that Windows Store App throw invalid handle exception.

    To handle the exception, use try-catch or you can register a app level unhandledException.

    App::App()
    {
    	InitializeComponent();
    	Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
    	UnhandledException += ref new Windows::UI::Xaml::UnhandledExceptionEventHandler(this, &App255::App::OnUnhandledException);
    }

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Tuesday, January 20, 2015 2:55 AM
    Moderator
  • Hi James,

    Thanks for the response.  

    I tried adding exception handlers but couldn't get anything to work.  The app always terminates.

    I added the code above to the stream socket c++ sample within the MainPage constructor (mainpage.xaml.cpp).  I wrapped this code in a try..catch.  I also added an unhandled exception handler to the app constructor (app.xaml.cpp) as follows:

    UnhandledException += ref new Windows::UI::Xaml::UnhandledExceptionEventHandler(
            [](::Platform::Object^ sender, ::Windows::UI::Xaml::UnhandledExceptionEventArgs^ e)
        {
        });

    None of these approaches catches the exception.  Could you try?

    Windows 8.1 Visual Studio 2013 update 4.

    Thanks.

    Tuesday, January 20, 2015 10:03 AM
  • Can anyone comment?
    Friday, January 23, 2015 3:27 PM
  • Can you capture the exception in a debugger and provide more details about it? Be sure to enable the Microsoft symbol server to get a deatiled stack, and set the debugger to break on exceptions.
    Saturday, January 24, 2015 5:57 AM
  • Exception and call stack:

    Unhandled exception at 0x7744A56C (ntdll.dll) in StreamSocket.Windows.exe: 0xC0000008: An invalid handle was specified.

    ntdll.dll!_NtQueryObject@20() Unknown
    KernelBase.dll!_GetHandleInformation@8() Unknown
    ws2_32.dll!DSOCKET::FindIFSSocket(unsigned int) Unknown
    ws2_32.dll!Prolog_Detached(class DPROCESS * *,class DTHREAD * *) Unknown
    StreamSocket.Windows.exe!SDKSample::MainPage::MainPage() Line 40 C++
    StreamSocket.Windows.exe!<lambda_766ef09d17676e69659eff295058f193>::<helper_func_cdecl>() Line 167 C++
    StreamSocket.Windows.exe!XamlTypeInfo::InfoProvider::XamlUserType::[Windows::UI::Xaml::Markup::IXamlType]::ActivateInstance() Line 339 C++
    StreamSocket.Windows.exe!XamlTypeInfo::InfoProvider::XamlUserType::[Windows::UI::Xaml::Markup::IXamlType]::__abi_Windows_UI_Xaml_Markup_IXamlType____abi_ActivateInstance(Platform::Object ^ * __abi_returnValue) C++
    Windows.UI.Xaml.dll!DirectUI::TypeInfo::CreateInstance(IInspectable * pOuter, IInspectable * * ppNewInstance) Line 2591 C++
    Windows.UI.Xaml.dll!DirectUI::NavigationCache::LoadContent(HSTRING__ * descriptor, IInspectable * * ppIInspectable) Line 148 C++
    Windows.UI.Xaml.dll!DirectUI::NavigationCache::GetContent(DirectUI::PageStackEntry * pPageStackEntry, IInspectable * * ppIInspectable) Line 98 C++
    Windows.UI.Xaml.dll!DirectUI::Frame::PerformNavigation() Line 452 C++
    Windows.UI.Xaml.dll!DirectUI::Frame::StartNavigation() Line 374 C++
    Windows.UI.Xaml.dll!DirectUI::Frame::NavigateImpl(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * pIInspectable, Windows::UI::Xaml::Media::Animation::INavigationTransitionInfo * navigationTransitionInfo, unsigned char * pCanNavigate) Line 345 C++
    Windows.UI.Xaml.dll!DirectUI::FrameGenerated::Navigate(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * parameter, Windows::UI::Xaml::Media::Animation::INavigationTransitionInfo * infoOverride, unsigned char * returnValue) Line 51851 C++
    Windows.UI.Xaml.dll!DirectUI::Frame::NavigateImpl(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * pIInspectable, unsigned char * pCanNavigate) Line 304 C++
    Windows.UI.Xaml.dll!DirectUI::FrameGenerated::Navigate(Windows::UI::Xaml::Interop::TypeName sourcePageType, IInspectable * parameter, unsigned char * returnValue) Line 51838 C++
    StreamSocket.Windows.exe!Windows::UI::Xaml::Controls::IFrame::Navigate(Windows::UI::Xaml::Interop::TypeName __param0, Platform::Object ^ __param1) C++
    StreamSocket.Windows.exe!SDKSample::App::OnLaunched::__l15::<lambda>(Concurrency::task<void> prerequisite) Line 79 C++

    Saturday, January 24, 2015 9:23 PM
  • Also applies to Windows 10 build 9926
    Monday, January 26, 2015 2:17 PM
  • Thanks for the report and details. From a quick discussion with the winsock folks, there's nothing different in WinSock 2.x itself for Win32 vs. Windows Store usage so this should not be a general problem or behavior.

    Your particular repro requires reusing a socket after it's been closed which is (a) dangerous generally in terms of race conditions, and (b) a violation of the API constraints. I wonder if there's any other case where you are seeing an exception thrown rather than an error code?

    Otherwise, this may be a case of "Doctor, it hurts when I do this?" "Then don't do it."

    If your concern here is that there may be a lurking case of this specific repro in your code, be sure to use the Application Verifier with the "Net" and "Basics:Handle" tests

    Sunday, February 01, 2015 6:26 PM
  • Hi Chuck,

    Thanks for the reply.  I appreciate that the code reusing a closed socket is wrong but it will take some time to fix all cases which we would rather leave until we can refactor it correctly in a subsequent project.

    Have you tried the code above in a sample app? Can you catch the exception?

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET thesocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    closesocket(thesocket);

    u_long s = 0;
    int err = ioctlsocket(thesocket, FIONREAD, &s);

    Thanks

    Monday, February 02, 2015 1:09 PM