هل يقوم نظام التشغيل Vista بإجراء فحص أكثر صرامة لمعرفات الواجهة في مكالمات DCOM؟(تلقى كعب الروتين بيانات سيئة)؟

StackOverflow https://stackoverflow.com/questions/63720

  •  09-06-2019
  •  | 
  •  

سؤال

آمل أن يعذر الجميع طول هذا السؤال وأسلوبه السردي.قررت أن أصف الوضع بشيء من التفصيل في مدونتي.رأيت لاحقًا دعوة جويل إلى هذا الموقع، واعتقدت أنني سألصقها هنا لمعرفة ما إذا كان لدى أي شخص أي فكرة عن الموقف.

لقد كتبت، وأدعم الآن، تطبيقًا يتكون من عميل Visual Basic سميك يتحدث DCOM إلى مكونات COM+ من الطبقة المتوسطة المكتوبة بلغة C++ باستخدام ATL.يتم تشغيله في جميع مكاتبنا الثمانية.يستضيف كل مكتب خادمًا خلفيًا يحتوي على تطبيق COM+ (يتكون من 18 مكونًا منفصلاً) وSQLServer.عادةً ما يكون SQLServer موجودًا على نفس الخادم الخلفي، ولكن ليس من الضروري أن يكون كذلك.

لقد قمنا مؤخرًا بترحيل الخادم الخلفي في أكبر مكاتبنا - نيويورك - من مجموعة MSC إلى جهاز افتراضي جديد مستضاف على تقنية ESX الخاصة ببرنامج VMWare.نظرًا لأن موقع تطبيق COM+ قد انتقل من الخادم القديم إلى خادم جديد باسم مختلف، فقد اضطررت إلى إعادة توجيه جميع العملاء حتى يتمكنوا من تنشيط تطبيق COM+ على الخادم الجديد.كان هذا الإجراء قديمًا، حيث أنني فعلت نفس الشيء بشكل أساسي مع العديد من مكاتبي الصغيرة التي خضعت لترقيات مماثلة للبنية التحتية.

وبدا كل شيء روتينيا، وفي صباح يوم الاثنين، كان المكتب بأكمله - حوالي 1000 محطة عمل تعمل بنظام التشغيل Windows XP - يعمل دون وقوع أي حادث على الخادم الجديد.ولكن بعد ذلك جاءت المكالمة من مجموعة الهاتف المحمول الخاصة بي - كان هناك محامٍ يعمل من المنزل باستخدام اتصال VPN وكان يتلقى خطأً غريبًا بعد إعادة توجيهه إلى الخادم الجديد:

Error on FillTreeView2 - The stub received bad data.

هاه؟لم أشاهد رسالة الخطأ هذه من قبل.هل كان الخادم الجديد؟لكن جميع محطات العمل في المكتب كانت تعمل بشكل جيد.طلبت من المجموعة المتنقلة إعادة المحامي إلى السيرفر القديم (الذي كان لا يزال قيد التشغيل)، واختفى الخطأ.إذن ما هو الفرق؟وتبين أن هذا المحامي كان يشغل نظام التشغيل Vista في المنزل.

نحن لا نقوم بتشغيل نظام التشغيل Vista في أي من مكاتبنا، ولكن لدينا بعض المحامين الذين يقومون بتشغيل نظام التشغيل Vista في المنزل (بعضهم بالتأكيد في مكتبي في نيويورك).أنا كذلك ولم أرى هذه المشكلة من قبل.للتأكد من وجود مشكلة، قمت بتشغيل الكمبيوتر المحمول الذي يعمل بنظام التشغيل Vista، وأشرته إلى الخادم الجديد، وحصلت على نفس الخطأ.لقد قمت بإعادته إلى الخادم القديم، وكان يعمل بشكل جيد.من الواضح أنه كانت هناك مشكلة ما في نظام التشغيل Vista والمكونات الموجودة على الخادم الجديد - وهي مشكلة لا يبدو أنها تؤثر على عملاء XP.ماذا يمكن أن يكون؟

المحطة التالية - سجل أخطاء التطبيق على جهاز الكمبيوتر المحمول الخاص بي.أدى هذا إلى مزيد من المعلومات حول الخطأ:

Source:        Microsoft-Windows-RPC-Events
Date:          9/2/2008 11:56:07 AM
Event ID:      10
Level:         Error
Computer:      DevLaptop
Description:   Application has failed to complete a COM call because an incorrect
interface ID was passed as a parameter.

The expected Interface ID was 00000555-0000-0010-8000-00aa006d2ea4, 
The Interface ID returned was 00000556-0000-0010-8000-00aa006d2ea4.

User Action - Contact the application vendor for updated version of the application.

قدمت معرفات الواجهة الدليل الذي أحتاجه لكشف اللغز.يعرّف معرف الواجهة "المتوقع" واجهة Recordset الخاصة بـ MDAC - الإصدار 2.1 من تلك الواجهة تحديدًا.تتوافق الواجهة "التي تم إرجاعها" مع إصدار أحدث من Recordset (الإصدار 2.5 الذي يختلف عن الإصدار 2.1 من خلال تضمين إدخال إضافي واحد في نهاية vtable -- طريقة الحفظ).

في الواقع، تكشف واجهات المكون الخاص بي عن العديد من الأساليب التي تمرر مجموعة السجلات كمعلمة إخراج.فهل أعادوا فجأة إصدارًا أحدث من Recordset - بمعرف واجهة مختلف؟ويبدو أن هذا هو الحال بالتأكيد.ثم فكرت لماذا يجب أن يكون الأمر مهمًا.يبدو vtable هو نفسه لعملاء الواجهة الأقدم.في الواقع، أظن أننا إذا كنا نتحدث عن COM قيد التشغيل، وليس DCOM، فسيتم تجاهل عدم تطابق المعاوقة غير الضار هذا بصمت ولن يسبب أي مشاكل.

بالطبع، عندما يتم تفعيل حدود العملية والجهاز، يكون هناك وكيل وكعب روتين بين العميل والخادم.في هذه الحالة، كنت أستخدم تنظيم مكتبة النوع باستخدام منظم الخيوط المجاني.لذلك كان هناك لغزان يجب حلهما:

لماذا أعيد واجهة مختلفة في معلمات الإخراج من الأساليب الموجودة على الخادم الجديد الخاص بي؟

لماذا يؤثر هذا على عملاء Vista فقط؟

نظرًا لأن برنامج الخادم الخاص بي كان مستضافًا على خوادم في كل مكتب من مكاتبي الثمانية، فقد قررت أن أحاول توجيه عميل Vista الخاص بي إلى جميع هذه الخوادم بالتسلسل لمعرفة أي منها لديه مشكلات مع Vista وأي منها لا يعاني.اختبار مضيئة.لا تزال بعض الخوادم القديمة تعمل مع نظام التشغيل Vista ولكن الخوادم الأحدث لا تعمل.على الرغم من أن بعض الخوادم القديمة كانت لا تزال تعمل بنظام التشغيل Windows 2000 بينما كانت الخوادم الأحدث تعمل بنظام التشغيل Windows 2003، إلا أنه لا يبدو أن هذه هي المشكلة.

بعد مقارنة تواريخ ملفات DLL المكونة، ظهر أنه كلما أشار العميل إلى خوادم تحتوي على مكونات DLL مؤرخة قبل 2003، كان نظام التشغيل Vista على ما يرام.ولكن تلك التي لديها مكتبات الارتباط الحيوي (DLL) بتواريخ بعد عام 2003 كانت تمثل مشكلة.صدق أو لا تصدق، لم تكن هناك (أو على الأقل لم تكن هناك تغييرات مهمة) على التعليمات البرمجية الموجودة على مكونات الخادم منذ سنوات عديدة.من الواضح أن التواريخ المختلفة كانت ببساطة بسبب إعادة ترجمة المكونات الخاصة بي على جهاز (أجهزة) التطوير الخاص بي.ويبدو أن إحدى هذه العمليات تمت في عام 2003.

استمر المصباح الكهربائي.عند تمرير مجموعات السجلات مرة أخرى من الخادم إلى العميل، تشير مكونات ATL C++ الخاصة بي إلى الواجهة باسم _Recordset.يأتي هذا الرمز من مكتبة النوع المضمنة في msado15.dll.هذا هو السطر الذي كان لدي في كود C++:

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" no_namespace rename ( "EOF", "adoEOF" )

لا تنخدع بالـ 15 الموجودة في msdad15.dll.يبدو أن ملف DLL هذا لم يغير اسمه في السلسلة الطويلة من إصدارات MDAC.

عندما قمت بتجميع التطبيق في ذلك اليوم، كان إصدار MDAC هو 2.1.لذلك تم تجميع _Recordset باستخدام معرف الواجهة 2.1 وهي الواجهة التي يتم إرجاعها بواسطة الخوادم التي تقوم بتشغيل هذه المكونات.

يستخدم جميع العملاء وكيل تطبيق COM + الذي تم إنشاؤه (على ما أعتقد) في عام 1999.تتضمن مكتبة النوع التي تحدد واجهاتي السطر:

importlib("msado21.tlb");

وهو ما يفسر سبب توقعهم للإصدار 2.1 من Recordset في معلمات إخراج طريقتي.من الواضح أن المشكلة كانت في إعادة الترجمة لعام 2003 وحقيقة أن رمز _Recordset في ذلك الوقت لم يعد يتوافق مع الإصدار 2.1.في الواقع تتوافق _Recordset مع الإصدار 2.5 بمعرف الواجهة المميز الخاص بها.كان الحل بالنسبة لي هو تغيير كافة المراجع من _Recordset إلى Recordset21 في كود C++ الخاص بي.لقد قمت بإعادة بناء المكونات ونشرتها على الخادم الجديد.Voila - بدا العملاء سعداء مرة أخرى.

في الختام، هناك سؤالان مزعجان لا يزالان عالقين في ذهني.

لماذا يبدو أن البنية التحتية للوكيل/كعب الروتين تتصرف بشكل مختلف مع عملاء Vista؟يبدو أن نظام التشغيل Vista يقوم بإجراء عمليات فحص أكثر صرامة لمعرفات الواجهة التي تعود من معلمات الطريقة مقارنةً بنظام التشغيل XP.

كيف كان يجب عليّ ترميز هذا بشكل مختلف في عام 1999 حتى لا يحدث هذا؟من المفترض أن تكون الواجهات غير قابلة للتغيير، وعندما قمت بإعادة الترجمة ضمن إصدار أحدث من MDAC، قمت بتغيير الواجهة عن غير قصد لأن الأساليب الآن أعادت واجهة Recordset مختلفة كمعلمة إخراج.بقدر ما أعرف، لم يكن لدى مكتبة النوع في ذلك الوقت رمز خاص بالإصدار - أي أن الإصدارات الأحدث من مكتبات الأنواع MDAC تحدد Recordset21، لكن هذا الرمز لم يكن متاحًا مرة أخرى في مكتبة الأنواع 2.1.

هل كانت مفيدة؟

المحلول

عندما حصلت Microsoft على دين الأمان، حظي DCOM (و RPC الأساسي) بالكثير من الاهتمام، وكانت هناك بالتأكيد تغييرات تم إجراؤها لإغلاق الثغرات الأمنية التي أدت إلى تنظيم أكثر صرامة.أنا مندهش أنك ترى هذا في نظام التشغيل Vista ولكن ليس في نظام التشغيل XP، ولكن من الممكن أن تتم إضافة عمليات فحص إضافية لنظام التشغيل Vista.وبدلاً من ذلك، من الممكن أن تكون الصرامة الاختيارية في XP قد أصبحت إلزامية في Vista.

على الرغم من أنني لا أعرف ما يكفي عن MDAC لمعرفة ما إذا كان بإمكانك منع ذلك، إلا أنني أعلم أن الأمان هو أحد المجالات القليلة التي تكون Microsoft على استعداد تام للتضحية فيها بالتوافق مع الإصدارات السابقة، لذا فمن الممكن ألا تتمكن من فعل أي شيء " أفضل" في عام 1999.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top